Module5-SocketIO-Test
AJAX is useful when one-way communication is satisfactory for your web application. However, what happens when you need two-way communication, like a chat client, collaborative whiteboard, live dashboard, or multiplayer game? AJAX isn't the tool for the job. This is where Socket.IO comes in.
Socket.IO is a library that enables low-latency, bidirectional, event-based communication between the server and the client. One key advantage is that the server can send messages to the client without the client having to ask first (as is the case with traditional AJAX polling). As you learn Socket.IO, the Node.js idea of non-blocking I/O will become your best friend! :contentReference[oaicite:0]{index=0}
Contents
Installing Socket.IO
Before you install Socket.IO, you need to install Node.JS (which includes npm). We strongly recommend using the current Node LTS.
Socket.IO is installed per-project (locally). This means you should cd to the project folder where your server code will live, then run:
$ npm init -y
$ npm install socket.io
:contentReference[oaicite:1]{index=1}
Note on "global" installs: If you pass -g to npm install, the package is installed globally. For course projects, avoid global installs unless you are very confident you understand why you need them. Local installs make your project portable and reproducible.
A note about modern Node (ES Modules)
Modern Node.js uses ES Modules (import/export) instead of the older require() syntax.
To enable ES Modules, add this line to your package.json:
{
"type": "module"
}
If you do not want to use ES Modules, you can still use CommonJS (require), but all examples below use modern ESM syntax.
Messaging
Socket.IO works by having clients and servers send named events to each other.
For example:
// Computer A:
socket.emit("info", {
hello: "world"
});
// Computer B:
socket.on("info", (data) => {
console.log(data.hello);
});
Computer A could be either the client or the server, and Computer B would be the other. When socket.emit(name, data) is called on either end, any listeners registered with socket.on(name, ...) on the other end will run and receive the data.
This event-based model is inspired by Node's EventEmitter style: emit events on one side, listen on the other. :contentReference[oaicite:2]{index=2}
A First Socket.IO Application: Chat Server and Client
Building a chat client is surprisingly simple using Socket.IO and Node.js, and it gives great insight into how Socket.IO works. Take the time to understand how this example works. If you understand this, adding more features (usernames, rooms, typing indicators, etc.) becomes 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";
/*
Mini static server:
- serves ONLY client.html for any request
- Socket.IO also exposes a client bundle at /socket.io/socket.io.js
*/
const httpServer = createServer(async (req, res) => {
try {
const data = await readFile(file);
res.writeHead(200, { "Content-Type": "text/html" });
res.end(data);
} catch (err) {
res.writeHead(500, { "Content-Type": "text/plain" });
res.end("Server error: could not read client.html");
}
});
// Attach Socket.IO to the HTTP server:
const io = new Server(httpServer);
io.on("connection", (socket) => {
// Runs when a new Socket.IO connection is established
console.log("New connection:", socket.id);
socket.on("message_to_server", (data) => {
// Runs when the server receives a new message from a client
console.log("message:", data.message);
// Send to everyone (including the sender):
io.emit("message_to_client", { message: data.message });
// If you wanted: send to everyone EXCEPT the sender:
// socket.broadcast.emit("message_to_client", { message: data.message });
});
});
httpServer.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
What this server does:
- Creates a basic HTTP server that serves a single file, client.html.
- Attaches a Socket.IO server to that HTTP server.
- Listens for a client event called message_to_server.
- When a message arrives, it broadcasts a message_to_client event to connected clients.
Important note: By default, the Socket.IO server exposes a browser client bundle at /socket.io/socket.io.js which we use from the HTML page. :contentReference[oaicite:3]{index=3}
The Chat Client
Create client.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.IO Chat Demo</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(); // connects back to the same host/port
socket.on("message_to_client", (data) => {
// Append an HR and then the message as text (safe against XSS)
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 = "";
input.focus();
}
document.getElementById("send_btn").addEventListener("click", sendMessage);
// Optional: press Enter to send
document.getElementById("message_input").addEventListener("keydown", (e) => {
if (e.key === "Enter") sendMessage();
});
</script>
</body>
</html>
Note: This example sends an object ({message: ...}) as the event data, but you can send any JavaScript datatype, including numbers, strings, arrays, and object literals.
Also notice that we display messages using createTextNode(), which treats content as plain text (helpful to avoid XSS when printing user-generated input).
Running the Example
Save chat-server.js and client.html in the same directory, then:
$ node chat-server.js
Open your browser to:
Open the page in two windows (or two different browsers). Now type messages — you have a (very basic) chat client!
Broadcasting: "everyone" vs "everyone else"
Socket.IO gives you multiple ways to send events:
- io.emit(...) sends to everyone connected (including the sender).
- socket.broadcast.emit(...) sends to everyone except the sender.
- io.to(room).emit(...) sends only to sockets in a specific room (see below).
Broadcasting is a server-side feature. :contentReference[oaicite:4]{index=4}
Rooms (and why you care)
Rooms are a server-only concept that let you group sockets together so you can broadcast to a subset of clients (for example: one chat room per group). :contentReference[oaicite:5]{index=5}
Basic idea:
- A socket can join and leave rooms.
- You can emit to everyone in a room.
Example (server-side):
io.on("connection", (socket) => {
socket.on("join_room", (data) => {
socket.join(data.room);
});
socket.on("room_message", (data) => {
// send only to people in that room
io.to(data.room).emit("message_to_client", { message: data.message });
});
});
Rooms make it much easier to build:
- group chats
- team-based games
- collaborative apps with separate workspaces
Resources
- Socket.IO documentation (v4): https://socket.io/docs/v4/ :contentReference[oaicite:6]{index=6}
- Server installation: https://socket.io/docs/v4/server-installation/ :contentReference[oaicite:7]{index=7}
- Client installation (including /socket.io/socket.io.js): https://socket.io/docs/v4/client-installation/ :contentReference[oaicite:8]{index=8}
- Rooms: https://socket.io/docs/v4/rooms/ :contentReference[oaicite:9]{index=9}