Socket.IO is a library that enables real-time, bidirectional, and event-based communication between web clients and servers. It's built on top of WebSockets but includes fallbacks to other technologies (like HTTP long-polling) for older browsers, making it incredibly reliable.

The entire library is built around a simple and powerful idea: emitting and listening for events.

Core Concept: Events

Think of events like sending and receiving notifications. One side emits an event with a custom name and some data, and the other side sets up a listener using on to catch and react to that event.

  • socket.emit(eventName, data): Sends an event from one socket.
  • socket.on(eventName, (data) => { ... }): Listens for an event on one socket.

Client and Server Setup

Server-Side (Node.js): The server waits for clients to connect.

JavaScript


// server.js
import { Server } from "socket.io";

// Create a Socket.IO server attached to an HTTP server
const io = new Server(3000);

// Listen for a new client connection
io.on('connection', (socket) => {
  console.log(`A user connected with ID: ${socket.id}`);

  // Listen for a 'client-message' event from this specific client
  socket.on('client-message', (msg) => {
    console.log(`Message from ${socket.id}: ${msg}`);
  });
});

Client-Side (Browser): The client tries to connect to the server.

HTML


<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io(); // Connects to the server

  // This fires when the connection is successful
  socket.on('connect', () => {
    console.log(`Connected to server with ID: ${socket.id}`);
    
    // Emit a 'client-message' event to the server
    socket.emit('client-message', 'Hello from the client!');
  });
</script>

Broadcasting: Talking to Everyone Else

What if you want to send a message to every connected client except the one who sent it? This is called broadcasting. A perfect example is a chat room, where one user's message should be seen by all other users.

You can achieve this with socket.broadcast.emit().

Code Snippet: A Simple Broadcast

JavaScript


// server.js
io.on('connection', (socket) => {
  // Listen for a 'chat-message' from a client
  socket.on('chat-message', (msg) => {
    // Broadcast this message to all other clients
    socket.broadcast.emit('new-chat-message', msg);
  });
});

If Client A sends a 'chat-message', Clients B and C will receive the 'new-chat-message' event, but Client A will not.

Rooms: Creating Channels

Rooms are channels that sockets can join and leave. They provide a powerful way to segment your clients into groups. For example, you could have rooms for specific chat topics, document collaboration sessions, or notification groups.

  • socket.join('roomName'): Makes a socket join a room.
  • socket.leave('roomName'): Makes a socket leave a room.
  • io.to('roomName').emit(...): Emits an event to every socket inside a specific room.

Code Snippet: Using Rooms

Let's imagine a system where users can get notifications about different sports.

JavaScript


// server.js
io.on('connection', (socket) => {
  // Client can tell the server which team's room to join
  socket.on('join-team-room', (teamName) => {
    socket.join(teamName);
    console.log(`${socket.id} joined the ${teamName} room.`);
    
    // Send a welcome message only to the client that just joined
    socket.emit('welcome-message', `Welcome to the ${teamName} fan club!`);
  });
});

// Elsewhere in your application, you might send a score update
function sendScoreUpdate(teamName, score) {
  // This sends an event ONLY to clients in the specified room
  io.to(teamName).emit('score-update', score);
}

// Example usage:
// sendScoreUpdate('team-red', 'Red: 1, Blue: 0');

In this example, only the clients who joined the 'team-red' room will receive the score update.