Socket.io Client Setup
The Socket.io client library allows web browsers and Node.js applications to connect to Socket.io servers. It handles connection management, reconnection logic, and provides an intuitive API for real-time communication.
Installing the Client Library
There are multiple ways to include the Socket.io client in your project:
<!-- Option 1: CDN (easiest for testing) -->
<script src="https://cdn.socket.io/4.6.0/socket.io.min.js"></script>
<!-- Option 2: NPM (recommended for production) -->
npm install socket.io-client
<!-- Option 3: Served by Socket.io server -->
<script src="/socket.io/socket.io.js"></script>
Note: When using a bundler (Vite, Webpack, etc.), always install via npm. The CDN approach is only suitable for quick prototypes and learning.
Basic Client Connection
Here's how to establish a connection from the browser:
<!-- HTML -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.io Client</title>
</head>
<body>
<h1>Socket.io Client</h1>
<div id="status">Disconnected</div>
<div id="messages"></div>
<script src="https://cdn.socket.io/4.6.0/socket.io.min.js"></script>
<script>
// Connect to server
const socket = io('http://localhost:3000');
// Connection successful
socket.on('connect', () => {
console.log('Connected with ID:', socket.id);
document.getElementById('status').textContent = 'Connected';
});
// Connection failed
socket.on('connect_error', (error) => {
console.error('Connection error:', error);
document.getElementById('status').textContent = 'Error';
});
// Disconnected
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
document.getElementById('status').textContent = 'Disconnected';
});
</script>
</body>
</html>
Using Socket.io Client with Modern JavaScript
In a Vite or React project with npm installation:
// main.js or app.js
import { io } from 'socket.io-client';
// Connect to server
const socket = io('http://localhost:3000', {
autoConnect: true, // Connect automatically (default)
reconnection: true, // Enable reconnection (default)
reconnectionDelay: 1000, // Wait 1s before reconnecting
reconnectionAttempts: 5 // Try 5 times
});
// Connection events
socket.on('connect', () => {
console.log('Connected! Socket ID:', socket.id);
});
socket.on('disconnect', (reason) => {
console.log('Disconnected because:', reason);
if (reason === 'io server disconnect') {
// Server forcefully disconnected, manually reconnect
socket.connect();
}
});
socket.on('connect_error', (error) => {
console.error('Failed to connect:', error.message);
});
Connection Options
The client accepts many options to customize behavior:
const socket = io('http://localhost:3000', {
// Connection options
autoConnect: true, // Connect immediately
reconnection: true, // Enable auto-reconnection
reconnectionDelay: 1000, // Initial delay (ms)
reconnectionDelayMax: 5000, // Maximum delay (ms)
reconnectionAttempts: Infinity, // Number of attempts
// Transport options
transports: ['websocket', 'polling'], // Preferred transports
upgrade: true, // Upgrade from polling to WebSocket
// Authentication
auth: {
token: 'your-auth-token',
userId: '12345'
},
// Query parameters (sent in URL)
query: {
room: 'general',
username: 'John'
},
// Timeout settings
timeout: 20000, // Connection timeout (ms)
// Path (if server uses custom path)
path: '/socket.io/'
});
Tip: Use auth for sensitive data like tokens (sent in handshake), and query for non-sensitive data like room names (visible in URL).
Emitting Events from Client
Send custom events to the server using emit():
// Simple event with string
socket.emit('greeting', 'Hello Server!');
// Event with object
socket.emit('chatMessage', {
room: 'general',
message: 'Hello everyone!',
timestamp: Date.now()
});
// Event with multiple arguments
socket.emit('userAction', 'click', 'button-1', { x: 100, y: 200 });
// Event with callback (acknowledgement)
socket.emit('saveData', { name: 'John' }, (response) => {
if (response.success) {
console.log('Data saved!');
} else {
console.error('Error:', response.error);
}
});
Listening for Events from Server
Receive events from the server using on():
// Listen for welcome message
socket.on('welcome', (message) => {
console.log('Server says:', message);
alert(message);
});
// Listen for chat messages
socket.on('chatMessage', (data) => {
const messagesDiv = document.getElementById('messages');
messagesDiv.innerHTML += `
<div class="message">
<strong>${data.id}:</strong> ${data.message}
<span class="time">${new Date(data.timestamp).toLocaleTimeString()}</span>
</div>
`;
});
// Listen for user count updates
socket.on('userCount', (count) => {
document.getElementById('user-count').textContent = count;
});
// Listen for typing indicator
socket.on('userTyping', (data) => {
console.log(`User ${data.userId} is ${data.isTyping ? 'typing' : 'stopped typing'}`);
});
Handling Disconnection
Properly handle disconnection scenarios:
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
switch(reason) {
case 'io server disconnect':
// Server forcefully disconnected this socket
// Need to manually reconnect
console.log('Server kicked us out. Reconnecting...');
socket.connect();
break;
case 'io client disconnect':
// We manually disconnected
console.log('We disconnected ourselves');
break;
case 'ping timeout':
// Server didn't respond to ping in time
console.log('Connection timeout. Will auto-reconnect');
break;
case 'transport close':
// Connection lost (network issue)
console.log('Connection lost. Will auto-reconnect');
break;
case 'transport error':
// Transport error (e.g., CORS)
console.log('Transport error. Will auto-reconnect');
break;
}
});
// Track reconnection attempts
socket.io.on('reconnect_attempt', (attemptNumber) => {
console.log(`Reconnection attempt ${attemptNumber}`);
});
socket.io.on('reconnect', (attemptNumber) => {
console.log(`Reconnected after ${attemptNumber} attempts`);
});
socket.io.on('reconnect_failed', () => {
console.log('Failed to reconnect after all attempts');
alert('Unable to connect to server. Please refresh the page.');
});
Connection Query Parameters
Pass data during connection handshake:
// Client sends query parameters
const socket = io('http://localhost:3000', {
query: {
username: 'John',
room: 'general',
token: 'abc123'
}
});
// Server receives query parameters
io.on('connection', (socket) => {
console.log('Query:', socket.handshake.query);
// { username: 'John', room: 'general', token: 'abc123' }
const username = socket.handshake.query.username;
const room = socket.handshake.query.room;
// Auto-join room based on query
socket.join(room);
// Send personalized welcome
socket.emit('welcome', `Welcome ${username} to ${room}!`);
});
Warning: Query parameters are visible in the URL and network logs. Don't use them for sensitive authentication tokens. Use the auth option instead.
Manual Connection Control
Connect and disconnect programmatically:
// Create socket without auto-connecting
const socket = io('http://localhost:3000', {
autoConnect: false
});
// Manually connect when needed
document.getElementById('connect-btn').addEventListener('click', () => {
socket.connect();
});
// Manually disconnect
document.getElementById('disconnect-btn').addEventListener('click', () => {
socket.disconnect();
});
// Check connection status
if (socket.connected) {
console.log('Already connected');
} else {
console.log('Not connected');
}
Complete Client Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chat Client</title>
<style>
#status { padding: 10px; margin: 10px 0; border-radius: 5px; }
.connected { background: #d4edda; color: #155724; }
.disconnected { background: #f8d7da; color: #721c24; }
#messages { height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; }
.message { margin: 5px 0; padding: 5px; background: #f0f0f0; border-radius: 3px; }
</style>
</head>
<body>
<h1>Chat Application</h1>
<div id="status" class="disconnected">Connecting...</div>
<div>Users online: <span id="user-count">0</span></div>
<div id="messages"></div>
<input type="text" id="message-input" placeholder="Type a message...">
<button id="send-btn">Send</button>
<script src="https://cdn.socket.io/4.6.0/socket.io.min.js"></script>
<script>
const socket = io('http://localhost:3000');
const statusDiv = document.getElementById('status');
const messagesDiv = document.getElementById('messages');
const messageInput = document.getElementById('message-input');
const sendBtn = document.getElementById('send-btn');
// Connection status
socket.on('connect', () => {
statusDiv.textContent = `Connected (${socket.id})`;
statusDiv.className = 'connected';
});
socket.on('disconnect', () => {
statusDiv.textContent = 'Disconnected';
statusDiv.className = 'disconnected';
});
// User count updates
socket.on('userCount', (count) => {
document.getElementById('user-count').textContent = count;
});
// Receive messages
socket.on('message', (data) => {
messagesDiv.innerHTML += `
<div class="message">
<strong>${data.id}:</strong> ${data.message}
</div>
`;
messagesDiv.scrollTop = messagesDiv.scrollHeight;
});
// Send message
sendBtn.addEventListener('click', () => {
const message = messageInput.value.trim();
if (message) {
socket.emit('message', message);
messageInput.value = '';
}
});
// Send on Enter key
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendBtn.click();
}
});
</script>
</body>
</html>
Exercise: Create a Socket.io client that:
- Connects to your server with a custom username passed via query parameters
- Displays connection status with visual indicators (green/red)
- Shows the number of connected users in real-time
- Sends chat messages to the server
- Receives and displays messages from other users
- Handles reconnection gracefully with user feedback
- Includes a manual disconnect button