Socket.IO

From CSE330 Wiki
Jump to navigationJump to search

AJAX is useful when one-way communication is satisfactory for your web application. However, what happens when you need true two-way communication, such as a chat client, collaborative app, or multiplayer game? AJAX is not the right tool for that job. This is where Socket.IO comes in.

Socket.IO enables low-latency, bidirectional, event-based communication between the server and the client. Unlike AJAX polling, the server can send messages to the client without the client requesting them first. As you learn Socket.IO, the concept of non-blocking I/O in Node.js will become very important.

Installing Socket.IO

Before installing Socket.IO, you should already have Node.JS installed and be comfortable with the project setup used in the previous section (npm init, ES Modules, etc.).

If you are starting a new project:

$ mkdir chat
$ cd chat
$ npm init -y

Important: Ensure your package.json contains:

"type": "module"

This enables modern ES Module syntax (import).

Now install Socket.IO:

$ npm install socket.io

Socket.IO is installed locally inside node_modules and recorded automatically in package.json.

Messaging

Socket.IO uses an event-based model. Clients and servers send named events to each other.

Example:

// Sender (client or server)
socket.emit("info", { hello: "world" });

// Receiver (client or server)
socket.on("info", (data) => {
  console.log(data.hello);
});

When socket.emit(name, data) is called, any listener registered with socket.on(name, ...) will execute and receive the data.

Either side (client or server) can emit or receive events.

A First Socket.IO Application: Chat Server and Client

Building a simple chat application demonstrates the fundamentals of Socket.IO and real-time communication. Understanding this example will make later group features (rooms, private messaging, etc.) much easier.

The Chat Server

Create a file named chat-server.js:

import { createServer } from "node:http";
import { readFile } from "node:fs/promises";
import { Server } from "socket.io";

const port = 3456;
const file = "client.html";

// Minimal HTTP server that serves client.html
const httpServer = createServer(async (req, res) => {
  try {
    const data = await readFile(file);
    res.writeHead(200, { "Content-Type": "text/html" });
    res.end(data);
  } catch {
    res.writeHead(500, { "Content-Type": "text/plain" });
    res.end("Could not load client.html");
  }
});

// Attach Socket.IO to the HTTP server
const io = new Server(httpServer);

io.on("connection", (socket) => {
  console.log("New connection:", socket.id);

  socket.on("message_to_server", (data) => {
    console.log("message:", data.message);

    // Broadcast message to all connected clients
    io.emit("message_to_client", { message: data.message });
  });
});

httpServer.listen(port, () => {
  console.log(`Server running at http://localhost:${port}/`);
});

What this server does:

  • Serves client.html
  • Accepts Socket.IO connections
  • Listens for message_to_server events
  • Broadcasts messages to all clients

The Chat Client

Create client.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Socket.IO Chat</title>
</head>

<body>

<input type="text" id="message_input">
<button id="send_btn">Send</button>
<div id="chatlog"></div>

<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();

socket.on("message_to_client", (data) => {
  const chatlog = document.getElementById("chatlog");
  chatlog.appendChild(document.createElement("hr"));
  chatlog.appendChild(document.createTextNode(data.message));
});

function sendMessage() {
  const input = document.getElementById("message_input");
  const msg = input.value;
  socket.emit("message_to_server", { message: msg });
  input.value = "";
}

document.getElementById("send_btn").addEventListener("click", sendMessage);
</script>

</body>
</html>

This example sends a JavaScript object as event data, but any datatype may be used.

Running the Chat Server

Start the server:

$ node chat-server.js

Open:

http://localhost:3456/

Open the page in two browser windows. Messages typed in one window appear in the other — a simple real-time chat system.

If running on EC2, ensure port 3456 is open.

Broadcasting Behavior

Socket.IO supports several broadcast patterns:

  • io.emit(...) → send to all clients
  • socket.broadcast.emit(...) → send to all except sender
  • io.to(room).emit(...) → send to a specific room

Rooms (Concept)

Rooms allow grouping sockets so messages only go to certain users (e.g., chat rooms, game sessions).

Example:

io.on("connection", (socket) => {

  socket.on("join_room", (data) => {
    socket.join(data.room);
  });

  socket.on("room_message", (data) => {
    io.to(data.room).emit("message_to_client", {
      message: data.message
    });
  });

});

Rooms are managed on the server and are invisible to clients.

Resources