WebSocket Transport
The WebSocket transport provides persistent connections for IRPC, offering lower latency and real-time capabilities compared to HTTP.
Overview
WebSocket transport maintains a single persistent connection that handles multiple IRPC calls without reconnection overhead. This eliminates HTTP handshake latency and enables real-time communication patterns.
Installation
npm install @irpclib/wsBasic Usage
1. Declare Functions (Shared)
// rpc/hello/index.ts
import { irpc } from '../lib/module.js';
export type HelloFn = (name: string) => Promise<string>;
export const hello = irpc.declare<HelloFn>({ name: 'hello' });2. Implement Handlers (Server)
// rpc/hello/constructor.ts
import { irpc } from '../lib/module.js';
import { hello } from './index.js';
irpc.construct(hello, async (name) => `Hello ${name}`);3. Server Setup
// server.ts
import { WebSocketRouter } from '@irpclib/ws';
import { irpc, transport } from './lib/module.js';
import './rpc/hello/constructor.js';
const router = new WebSocketRouter(irpc, transport);
Bun.serve({
port: 8080,
fetch(req, server) {
if (server.upgrade(req)) return;
return new Response('WebSocket server running');
},
websocket: {
async message(ws, message) {
await router.resolve(message.toString(), ws);
},
},
});4. Client Usage
// client.ts
import { hello } from './rpc/hello/index.js';
const message = await hello('John');
console.log(message); // 'Hello John'Configuration
WebSocketTransportConfig
type WebSocketTransportConfig = {
// WebSocket connection
url: string; // WebSocket URL to connect to
protocols?: string[]; // Sub-protocols for the connection
// Reconnection
autoReconnect?: boolean; // Enable automatic reconnection (default: true)
maxReconnectAttempts?: number; // Maximum reconnection attempts (default: 5)
reconnectDelay?: number; // Delay between reconnection attempts (default: 1000ms)
// Timeouts
connectionTimeout?: number; // Connection establishment timeout (default: 10000ms)
timeout?: number; // Request timeout (inherited from base)
// Batching
debounce?: number | boolean; // Batching delay (inherited from base)
// Retry
maxRetries?: number; // Maximum retry attempts (inherited from base)
retryMode?: 'linear' | 'exponential'; // Retry strategy (inherited from base)
retryDelay?: number; // Base retry delay (inherited from base)
// Headers (for WebSocket upgrade request)
headers?: Record<string, string>;
};Connection Management
Connection States
The transport provides real-time connection state monitoring:
// Check current state
console.log(transport.state); // 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED
// Check if connected
if (transport.isOpen) {
await someFunction();
}Auto-Reconnection
WebSocket transport automatically handles connection failures:
const transport = new WebSocketTransport({
url: 'ws://localhost:8080',
autoReconnect: true,
maxReconnectAttempts: 5,
reconnectDelay: 1000, // 1 second between attempts
});
// Manual reconnection
await transport.reconnect();Connection Events
Monitor connection lifecycle:
// The transport handles reconnection internally
// Connection state can be checked via transport.state
// Calls are automatically queued during reconnectionPerformance Benefits
Lower Latency
- No HTTP handshake - Persistent connection eliminates TCP handshake overhead per request
- Immediate messaging - Messages sent without HTTP request/response cycle
- Connection reuse - Same WebSocket connection for multiple calls
Automatic Batching
Multiple simultaneous calls are batched into single WebSocket messages:
// These calls are batched into 1 WebSocket message
const [user, posts, stats] = await Promise.all([
getUser('123'),
getPosts('123'),
getStats('123'),
]);Streaming Responses
Because the WebSocket channel persists, responses are yielded dynamically as continuous IRPCPacketStream chunks over the socket. This enables you to attach .subscribe() across any standard pipeline to track real-time events.
Error Handling
Network Errors
WebSocket transport includes retry logic for network failures:
const transport = new WebSocketTransport({
url: 'ws://localhost:8080',
maxRetries: 3,
retryMode: 'exponential', // 1s, 2s, 4s delays
retryDelay: 1000,
});Network errors trigger automatic retries. Handler errors fail immediately without retry.
Connection Failures
Connection failures trigger reconnection attempts. Pending calls are queued and sent once reconnected.
Advanced Usage
Custom Headers
Include headers in the WebSocket upgrade request:
const transport = new WebSocketTransport({
url: 'ws://localhost:8080',
headers: {
'Authorization': 'Bearer token',
'X-API-Key': 'key',
},
});Middleware
Add middleware to the WebSocket router:
router.use(async () => {
// Access request context
const req = getContext<Request>('request');
// Validate authentication
const token = req.headers.get('authorization');
if (!token) {
throw new Error('Unauthorized');
}
// Set context for handlers
setContext('userId', decodeToken(token).userId);
});Custom Protocols
Specify WebSocket sub-protocols:
const transport = new WebSocketTransport({
url: 'ws://localhost:8080',
protocols: ['irpc', 'json'],
});Comparison with HTTP Transport
| Feature | WebSocket | HTTP |
|---|---|---|
| Connection Type | Persistent | Request/Response |
| Latency | Lower | Higher |
| Overhead | Minimal | HTTP headers |
| Real-time | Yes | No |
| Batching | Automatic | Automatic |
| Browser Support | Excellent | Universal |
| Setup Complexity | Medium | Simple |
Choose WebSocket transport when:
- You need persistent connections
- Lower latency is critical
- You're building real-time applications
- You want bidirectional communication
Choose HTTP transport when:
- You need maximum compatibility
- You're building REST-like APIs
- Simplicity is preferred
- You have existing HTTP infrastructure
Troubleshooting
Connection Issues
Problem: Connection fails to establish
Solutions:
- Check WebSocket URL format (
ws://orwss://) - Verify server is running and accepting WebSocket connections
- Check firewall/proxy settings
- Use browser dev tools to inspect WebSocket handshake
Reconnection Problems
Problem: Auto-reconnection not working
Solutions:
- Ensure
autoReconnect: trueis set - Check
maxReconnectAttemptsvalue - Verify server accepts reconnections
- Monitor
transport.statefor connection status
Performance Issues
Problem: High latency or slow responses
Solutions:
- Verify WebSocket connection is persistent
- Check for unnecessary reconnections
- Monitor batching efficiency
- Use appropriate timeout values
Next Steps
- Getting Started - Set up IRPC with WebSocket transport
- HTTP Transport - Alternative transport option
- Specification - Full protocol details