Client for the realtime Engine providing bidirectional communication with WebSocket, polling, and WebTransport support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive event system for monitoring connection lifecycle, data transmission, and error handling across all transport types with EventEmitter-based architecture.
Complete event system for monitoring socket connection lifecycle and data flow.
/**
* Socket event interface extending EventEmitter
* All events are strongly typed for development safety
*/
interface SocketReservedEvents {
// Connection lifecycle events
open: () => void;
handshake: (data: HandshakeData) => void;
close: (reason: string, description?: CloseDetails | Error) => void;
error: (err: string | Error) => void;
// Data transmission events
packet: (packet: Packet) => void;
packetCreate: (packet: Packet) => void;
data: (data: RawData) => void;
message: (data: RawData) => void;
// Flow control events
drain: () => void;
flush: () => void;
// Heartbeat events
heartbeat: () => void;
ping: () => void;
pong: () => void;
// Transport upgrade events
upgrading: (transport: Transport) => void;
upgrade: (transport: Transport) => void;
upgradeError: (err: Error) => void;
}Usage Examples:
import { Socket } from "engine.io-client";
const socket = new Socket("ws://localhost:3000");
// Connection lifecycle
socket.on("open", () => {
console.log("Connection established");
});
socket.on("close", (reason, description) => {
console.log("Connection closed:", reason);
if (description) {
console.log("Details:", description);
}
});
socket.on("error", (error) => {
console.error("Socket error:", error);
});Events for monitoring connection establishment, handshake, and termination.
/**
* Connection establishment event
* Fired when the connection is successfully opened
*/
on(event: "open", listener: () => void): Socket;
/**
* Handshake completion event
* Fired after successful handshake with server
*/
on(event: "handshake", listener: (data: HandshakeData) => void): Socket;
/**
* Connection close event
* Fired when connection is closed for any reason
*/
on(event: "close", listener: (reason: string, description?: CloseDetails | Error) => void): Socket;
/**
* Error event
* Fired when an error occurs on the connection
*/
on(event: "error", listener: (err: string | Error) => void): Socket;
interface HandshakeData {
sid: string;
upgrades: string[];
pingInterval: number;
pingTimeout: number;
maxPayload: number;
}
interface CloseDetails {
description: string;
context?: unknown;
}Usage Examples:
socket.on("handshake", (data) => {
console.log("Socket ID:", data.sid);
console.log("Available upgrades:", data.upgrades);
console.log("Ping interval:", data.pingInterval);
});
socket.on("close", (reason, description) => {
switch (reason) {
case "transport close":
console.log("Transport closed connection");
break;
case "ping timeout":
console.log("Connection timed out");
break;
case "transport error":
console.log("Transport error occurred");
break;
}
});Events for handling incoming and outgoing data packets.
/**
* Raw packet event
* Fired for every packet received from server
*/
on(event: "packet", listener: (packet: Packet) => void): Socket;
/**
* Packet creation event
* Fired when a packet is created for sending
*/
on(event: "packetCreate", listener: (packet: Packet) => void): Socket;
/**
* Data event
* Fired when data message is received
*/
on(event: "data", listener: (data: RawData) => void): Socket;
/**
* Message event (alias for data)
* Fired when message is received
*/
on(event: "message", listener: (data: RawData) => void): Socket;
interface Packet {
type: PacketType;
data?: RawData;
}
type PacketType = "open" | "close" | "ping" | "pong" | "message" | "upgrade" | "noop";
type RawData = string | Buffer | ArrayBuffer | ArrayBufferView | Blob;Usage Examples:
// Handle incoming messages
socket.on("message", (data) => {
if (typeof data === "string") {
const message = JSON.parse(data);
console.log("Received JSON:", message);
} else {
console.log("Received binary data:", data);
}
});
// Monitor all packets (debugging)
socket.on("packet", (packet) => {
console.log("Packet type:", packet.type);
if (packet.data) {
console.log("Packet data:", packet.data);
}
});
// Monitor outgoing packets
socket.on("packetCreate", (packet) => {
console.log("Sending packet:", packet.type);
});Events for monitoring buffer states and flow control mechanisms.
/**
* Drain event
* Fired when write buffer becomes empty
*/
on(event: "drain", listener: () => void): Socket;
/**
* Flush event
* Fired when buffered packets are flushed
*/
on(event: "flush", listener: () => void): Socket;Usage Examples:
// Monitor buffer drainage
socket.on("drain", () => {
console.log("Write buffer drained, ready for more data");
// Safe to send more data
socket.send("More data after drain");
});
// Monitor buffer flushing
socket.on("flush", () => {
console.log("Packets flushed to transport");
});
// Check buffer state before sending
if (socket.writeBuffer.length < 10) {
socket.send("data");
} else {
console.log("Buffer full, waiting for drain");
socket.once("drain", () => {
socket.send("data");
});
}Events for monitoring connection health through ping/pong mechanism.
/**
* Heartbeat event
* Fired periodically to indicate connection health
*/
on(event: "heartbeat", listener: () => void): Socket;
/**
* Ping event
* Fired when ping is sent to server
*/
on(event: "ping", listener: () => void): Socket;
/**
* Pong event
* Fired when pong is received from server
*/
on(event: "pong", listener: () => void): Socket;Usage Examples:
// Monitor connection health
socket.on("heartbeat", () => {
console.log("Connection heartbeat");
});
// Track ping/pong timing
let pingTime: number;
socket.on("ping", () => {
pingTime = Date.now();
console.log("Ping sent");
});
socket.on("pong", () => {
const latency = Date.now() - pingTime;
console.log("Pong received, latency:", latency + "ms");
});Events for monitoring transport upgrade process and handling upgrade failures.
/**
* Upgrading event
* Fired when transport upgrade process begins
*/
on(event: "upgrading", listener: (transport: Transport) => void): Socket;
/**
* Upgrade event
* Fired when transport upgrade completes successfully
*/
on(event: "upgrade", listener: (transport: Transport) => void): Socket;
/**
* Upgrade error event
* Fired when transport upgrade fails
*/
on(event: "upgradeError", listener: (err: Error) => void): Socket;Usage Examples:
// Monitor transport upgrades
socket.on("upgrading", (transport) => {
console.log("Starting upgrade to:", transport.name);
});
socket.on("upgrade", (transport) => {
console.log("Successfully upgraded to:", transport.name);
console.log("Transport supports binary:", transport.supportsBinary);
});
socket.on("upgradeError", (error) => {
console.error("Upgrade failed:", error.message);
console.log("Continuing with current transport");
});
// Disable upgrades if problematic
socket.on("upgradeError", () => {
socket.opts.upgrade = false;
console.log("Disabled further upgrade attempts");
});Standard EventEmitter methods for managing event listeners.
/**
* Add event listener
*/
on(event: keyof SocketReservedEvents, listener: Function): Socket;
/**
* Add one-time event listener
*/
once(event: keyof SocketReservedEvents, listener: Function): Socket;
/**
* Remove event listener
*/
off(event: keyof SocketReservedEvents, listener: Function): Socket;
/**
* Remove all listeners for event
*/
removeAllListeners(event?: keyof SocketReservedEvents): Socket;
/**
* Emit event (internal use)
*/
emit(event: keyof SocketReservedEvents, ...args: any[]): boolean;Usage Examples:
// Add persistent listener
const messageHandler = (data) => {
console.log("Message:", data);
};
socket.on("message", messageHandler);
// Add one-time listener
socket.once("open", () => {
console.log("Connected for the first time");
});
// Remove specific listener
socket.off("message", messageHandler);
// Remove all message listeners
socket.removeAllListeners("message");
// Remove all listeners
socket.removeAllListeners();type SocketEventNames = keyof SocketReservedEvents;
interface Transport extends Emitter {
name: string;
supportsBinary: boolean;
query: Record<string, string>;
writable: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-engine-io-client