The realtime engine behind Socket.IO providing bidirectional connection foundation between client and server
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Individual client connection management with bidirectional message passing, transport upgrades, and connection state tracking.
Represents an individual client connection with bidirectional communication capabilities.
/**
* Individual client connection with bidirectional communication
*/
class Socket extends EventEmitter {
/** Unique socket identifier (internal use only) */
private readonly id: string;
/** Protocol version (3 or 4) */
readonly protocol: number;
/** Current connection state */
readonly readyState: ReadyState;
/** Current transport instance */
readonly transport: Transport;
/** Initial HTTP request object */
readonly request: IncomingMessage;
/** Client IP address */
readonly remoteAddress: string;
/** Whether transport upgrade is in progress */
readonly upgrading: boolean;
/** Whether transport has been upgraded */
readonly upgraded: boolean;
/**
* Create socket instance (internal use)
* @param id - Unique socket identifier
* @param server - Parent server instance
* @param transport - Initial transport
* @param req - Extended HTTP request with Engine.IO properties
* @param protocol - Protocol version
*/
constructor(
id: string,
server: BaseServer,
transport: Transport,
req: EngineRequest,
protocol: number
);
}/**
* Send data to the client
* @param data - String or Buffer data to send
* @param options - Send options
* @param callback - Optional callback when sent
*/
send(
data: RawData,
options?: SendOptions,
callback?: (transport: Transport) => void
): Socket;
/**
* Alias for send() method
*/
write(
data: RawData,
options?: SendOptions,
callback?: (transport: Transport) => void
): Socket;Usage Examples:
// Send text message
socket.send('Hello client!');
// Send binary data
socket.send(Buffer.from([1, 2, 3, 4]));
// Send with compression disabled
socket.send('Large text data', { compress: false });
// Send with callback
socket.send('Message', undefined, (transport) => {
console.log('Message sent via transport:', transport.name);
});
// Method chaining (since send returns Socket)
socket.send('First message').send('Second message');/**
* Close the socket connection
* @param discard - Whether to discard the connection immediately
*/
close(discard?: boolean): void;Usage Example:
// Graceful close
socket.close();
// Immediate close (discard pending data)
socket.close(true);interface SocketEvents {
/** Emitted when socket connection is established */
open: () => void;
/** Emitted when socket connection is closed */
close: (reason: string, description?: any) => void;
/** Emitted when data is received from client */
data: (data: string | Buffer) => void;
/** Alias for 'data' event */
message: (data: string | Buffer) => void;
/** Emitted when a packet is received */
packet: (packet: Packet) => void;
/** Emitted when a packet is created for sending */
packetCreate: (packet: Packet) => void;
/** Emitted on ping/pong heartbeat */
heartbeat: () => void;
/** Emitted when transport upgrade starts */
upgrading: (transport: Transport) => void;
/** Emitted when transport upgrade completes */
upgrade: (transport: Transport) => void;
/** Emitted when write buffer is flushed */
flush: (buffer: any[]) => void;
/** Emitted when ready to write more data */
drain: () => void;
/** Emitted on socket errors */
error: (error: Error) => void;
}Usage Examples:
socket.on('open', () => {
console.log('Socket opened:', socket.id);
socket.send('Welcome!');
});
socket.on('message', (data) => {
console.log('Received from', socket.id, ':', data);
// Echo the message back
socket.send(`Echo: ${data}`);
});
socket.on('close', (reason, description) => {
console.log('Socket closed:', socket.id, reason);
});
socket.on('upgrade', (transport) => {
console.log('Transport upgraded to:', transport.name);
});
socket.on('error', (error) => {
console.error('Socket error:', error);
});/**
* Socket connection states
*/
enum ReadyState {
OPENING = "opening",
OPEN = "open",
CLOSING = "closing",
CLOSED = "closed"
}/**
* Options for sending messages
*/
interface SendOptions {
/** Whether to compress the message (default: true for large messages) */
compress?: boolean;
}// Server-side request-response
socket.on('message', (data) => {
const request = JSON.parse(data);
if (request.type === 'ping') {
socket.send(JSON.stringify({ type: 'pong', timestamp: Date.now() }));
}
});// Broadcast to all connected clients
function broadcast(message: string) {
Object.values(server.clients).forEach(socket => {
if (socket.readyState === 'open') {
socket.send(message);
}
});
}
// Usage
server.on('connection', (socket) => {
// Notify others of new connection
broadcast(`User ${socket.id} joined`);
socket.on('message', (data) => {
// Broadcast message to other clients
Object.values(server.clients).forEach(otherSocket => {
if (otherSocket !== socket && otherSocket.readyState === 'open') {
otherSocket.send(`${socket.id}: ${data}`);
}
});
});
socket.on('close', () => {
broadcast(`User ${socket.id} left`);
});
});socket.on('message', (data) => {
if (Buffer.isBuffer(data)) {
console.log('Received binary data:', data.length, 'bytes');
// Process binary data
const processed = processImageData(data);
socket.send(processed);
} else {
console.log('Received text data:', data);
socket.send(`Text echo: ${data}`);
}
});// Track active connections
const activeConnections = new Map<string, Socket>();
server.on('connection', (socket) => {
activeConnections.set(socket.id, socket);
console.log('Active connections:', activeConnections.size);
socket.on('close', () => {
activeConnections.delete(socket.id);
console.log('Active connections:', activeConnections.size);
});
});const MAX_CONNECTIONS = 1000;
server.on('connection', (socket) => {
if (server.clientsCount > MAX_CONNECTIONS) {
socket.send('Server full');
socket.close();
return;
}
// Handle connection normally
socket.on('message', handleMessage);
});socket.on('heartbeat', () => {
console.log('Heartbeat from:', socket.id);
socket.lastSeen = Date.now();
});
// Check for stale connections
setInterval(() => {
const now = Date.now();
Object.values(server.clients).forEach(socket => {
if (now - socket.lastSeen > 60000) { // 60 seconds
console.log('Closing stale connection:', socket.id);
socket.close();
}
});
}, 30000);