Using Socket.io
Integrate Socket.io with your Express app — set up the server, connect the client, and establish your first real-time connection.
Using Socket.io
Now that we have an Express server, it is time to add Socket.io and establish a real-time connection between the server and the browser. In this episode you will install Socket.io, integrate it with Express, and connect the client to the server.
Step 1: Install Socket.io
npm install socket.io
This installs the Socket.io server library. The client library is automatically served by the Socket.io server — you do not need to install it separately.
Step 2: Integrate Socket.io with Express
Update your index.js to use Socket.io:
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server);
app.use(express.static('public'));
// Listen for client connections
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
What Changed?
| Before | After | Why |
|---|---|---|
app.listen() | server.listen() | Socket.io needs the raw HTTP server, not the Express app |
| No http module | http.createServer(app) | Creates an HTTP server that Express and Socket.io share |
| No socket.io | new Server(server) | Attaches Socket.io to the HTTP server |
The key change is that we create the HTTP server manually with http.createServer(app) and pass it to both Socket.io and Express. Previously, app.listen() created the HTTP server internally — now we need direct access to it.
Understanding the Server Code
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
});
The io.on('connection') event fires every time a client connects. The socket parameter represents that specific client's connection. Each socket has a unique id that identifies the connection.
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
The disconnect event fires when a client loses connection — closing the tab, navigating away, or losing network connectivity.
Step 3: Connect the Client
Update your public/index.html to include the Socket.io client library and connect to the server. Add this before the closing </body> tag:
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on('connect', () => {
console.log('Connected to server with ID:', socket.id);
});
socket.on('disconnect', () => {
console.log('Disconnected from server');
});
</script>
How the Client Library Works
| Line | What It Does |
|---|---|
/socket.io/socket.io.js | Socket.io server automatically serves its client library at this URL |
io() | Connects to the Socket.io server that served the page (auto-detects the URL) |
socket.on('connect') | Fires when the connection is established successfully |
socket.on('disconnect') | Fires when the connection is lost |
You do not need to specify the server URL in io() — it automatically connects to the server that served the page. If you needed to connect to a different server, you would pass the URL: io('http://other-server:3000').
Step 4: Test the Connection
node index.js
Open http://localhost:3000 in your browser. In the terminal, you should see:
Server running on http://localhost:3000
A user connected: abc123xyz
Open the browser console (F12 → Console tab) and you should see:
Connected to server with ID: abc123xyz
If you close the browser tab, the terminal shows:
User disconnected: abc123xyz
Testing Multiple Connections
Open multiple browser tabs pointing to http://localhost:3000. Each tab creates a new socket connection with a unique ID. The server will log each connection separately. This demonstrates that Socket.io handles multiple simultaneous connections automatically.
How Socket.io Connects Under the Hood
1. Browser loads the page from Express (HTTP GET /)
2. Browser loads Socket.io client library (/socket.io/socket.io.js)
3. Client calls io() which sends an HTTP request with upgrade headers
4. Server responds with 101 Switching Protocols
5. Connection upgrades to WebSocket
6. Both sides can now emit events freely
7. Socket.io maintains the connection with heartbeats (ping/pong)
Socket.io also sends periodic "ping" messages to check if the connection is still alive. If the server does not receive a "pong" response, it considers the client disconnected.
Key Takeaways
- Socket.io requires the raw HTTP server — use
http.createServer(app)instead ofapp.listen() - The Socket.io server automatically serves its client library at
/socket.io/socket.io.js - Calling
io()on the client automatically connects to the server that served the page - Each connected client gets a unique
socket.idfor identification io.on('connection')fires on the server for every new client connection- Socket.io handles reconnection, heartbeats, and transport fallback automatically