or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdserver.mdsocket.mdtransports.mdtypes.md
tile.json

socket.mddocs/

Socket Connections

Individual client connection management with bidirectional message passing, transport upgrades, and connection state tracking.

Capabilities

Socket Class

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
  );
}

Socket Methods

Send Messages

/**
 * 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 Connection

/**
 * 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);

Socket Events

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);
});

Connection States

/**
 * Socket connection states
 */
enum ReadyState {
  OPENING = "opening",
  OPEN = "open", 
  CLOSING = "closing",
  CLOSED = "closed"
}

Send Options

/**
 * Options for sending messages
 */
interface SendOptions {
  /** Whether to compress the message (default: true for large messages) */
  compress?: boolean;
}

Real-time Communication Patterns

Request-Response Pattern

// 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 Pattern

// 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`);
  });
});

Binary Data Handling

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}`);
  }
});

Connection Management

Client Tracking

// 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);
  });
});

Connection Limits

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);
});

Heartbeat Monitoring

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);