0
# WebSocket Server
1
2
JSON-RPC 2.0 server implementation with method registration, event management, namespace support, and authentication middleware for building real-time WebSocket applications.
3
4
## Capabilities
5
6
### Server Constructor
7
8
Creates a WebSocket RPC server with configurable options and data serialization.
9
10
```typescript { .api }
11
/**
12
* WebSocket RPC server implementation
13
* Extends EventEmitter for connection and error handling
14
*/
15
class Server extends EventEmitter {
16
/** WebSocket Server instance for direct access to underlying server */
17
wss: InstanceType<typeof WebSocketServer>;
18
19
/**
20
* Instantiate a Server class
21
* @param options - WebSocket server constructor parameters
22
* @param dataPack - custom data pack for encoding/decoding messages
23
* @returns new Server instance
24
*/
25
constructor(
26
options: NodeWebSocket.ServerOptions,
27
dataPack?: DataPack<object, string>
28
);
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { Server } from "rpc-websockets";
36
37
// Basic server on specific port
38
const server = new Server({ port: 8080 });
39
40
// Server with host and port
41
const server = new Server({
42
host: "localhost",
43
port: 8080
44
});
45
46
// Server with custom options
47
const server = new Server({
48
port: 8080,
49
perMessageDeflate: false,
50
maxPayload: 16 * 1024 * 1024 // 16MB
51
});
52
53
// Server with external HTTP server
54
import { createServer } from "http";
55
const httpServer = createServer();
56
const server = new Server({ server: httpServer });
57
httpServer.listen(8080);
58
```
59
60
### Method Registration
61
62
Register RPC methods that clients can call, with support for protection levels.
63
64
```typescript { .api }
65
/**
66
* Registers an RPC method
67
* @param name - method name that clients will call
68
* @param fn - handler function receiving parameters and socket ID
69
* @param ns - namespace identifier (default: "/")
70
* @returns IMethod object with protection control methods
71
* @throws TypeError for invalid parameters
72
*/
73
register(
74
name: string,
75
fn: (params: IRPCMethodParams, socket_id: string) => any,
76
ns?: string
77
): IMethod;
78
79
interface IMethod {
80
/** Mark method as protected (requires authentication) */
81
protected(): void;
82
/** Mark method as public (default, no authentication required) */
83
public(): void;
84
}
85
86
interface IRPCMethodParams {
87
[x: string]: any;
88
}
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
// Simple public method
95
server.register("sum", (params) => {
96
return params[0] + params[1];
97
});
98
99
// Method with socket access
100
server.register("getUserInfo", (params, socket_id) => {
101
console.log(`Request from socket: ${socket_id}`);
102
return { id: params.id, name: "User Name" };
103
});
104
105
// Protected method requiring authentication
106
server.register("getSecretData", () => {
107
return { secret: "confidential information" };
108
}).protected();
109
110
// Method in custom namespace
111
server.register("adminCommand", (params) => {
112
return { status: "executed", command: params.command };
113
}, "/admin");
114
115
// Async method
116
server.register("fetchData", async (params) => {
117
const response = await fetch(params.url);
118
return await response.json();
119
});
120
```
121
122
### Authentication Setup
123
124
Configure authentication middleware for protecting methods and events.
125
126
```typescript { .api }
127
/**
128
* Sets an auth method for login functionality
129
* @param fn - authentication function returning Promise<boolean>
130
* @param ns - namespace identifier (default: "/")
131
*/
132
setAuth(
133
fn: (params: IRPCMethodParams, socket_id: string) => Promise<boolean>,
134
ns?: string
135
): void;
136
```
137
138
**Usage Examples:**
139
140
```typescript
141
// Simple username/password authentication
142
server.setAuth(async (params, socket_id) => {
143
const { username, password } = params;
144
145
// Validate credentials (example)
146
if (username === "admin" && password === "secret") {
147
console.log(`User ${username} authenticated from socket ${socket_id}`);
148
return true;
149
}
150
151
return false;
152
});
153
154
// Database-based authentication
155
server.setAuth(async (params, socket_id) => {
156
try {
157
const user = await database.validateUser(params.token);
158
if (user) {
159
console.log(`User ${user.id} authenticated`);
160
return true;
161
}
162
} catch (error) {
163
console.error("Auth error:", error);
164
}
165
return false;
166
});
167
168
// Namespace-specific authentication
169
server.setAuth(async (params) => {
170
return params.adminKey === "admin-secret";
171
}, "/admin");
172
```
173
174
### Event Management
175
176
Create and manage events that can be emitted to subscribed clients.
177
178
```typescript { .api }
179
/**
180
* Creates a new event that can be emitted to clients
181
* @param name - event name that clients can subscribe to
182
* @param ns - namespace identifier (default: "/")
183
* @returns IEvent object with protection control methods
184
* @throws TypeError if event already exists
185
*/
186
event(name: string, ns?: string): IEvent;
187
188
/**
189
* Lists all created events in a given namespace
190
* @param ns - namespace identifier (default: "/")
191
* @returns array of event names
192
*/
193
eventList(ns?: string): string[];
194
195
interface IEvent {
196
/** Mark event as protected (requires authentication to subscribe) */
197
protected(): void;
198
/** Mark event as public (default, no authentication required) */
199
public(): void;
200
}
201
```
202
203
**Usage Examples:**
204
205
```typescript
206
// Create public events
207
server.event("userJoined");
208
server.event("messagePosted");
209
server.event("feedUpdated");
210
211
// Create protected event
212
server.event("adminAlert").protected();
213
214
// Emit events to subscribers
215
server.emit("userJoined", {
216
userId: 123,
217
username: "alice",
218
timestamp: Date.now()
219
});
220
221
server.emit("messagePosted", {
222
messageId: 456,
223
content: "Hello world!",
224
author: "alice"
225
});
226
227
// List available events
228
const events = server.eventList();
229
console.log("Available events:", events);
230
231
// Events in specific namespace
232
server.event("specialEvent", "/admin");
233
const adminEvents = server.eventList("/admin");
234
```
235
236
### Namespace Management
237
238
Organize methods and events into separate namespaces for multi-tenant applications.
239
240
```typescript { .api }
241
/**
242
* Returns a requested namespace object with convenience methods
243
* @param name - namespace identifier
244
* @returns namespace object with scoped methods
245
*/
246
of(name: string): {
247
/** Register method in this namespace */
248
register(fn_name: string, fn: (params: IRPCMethodParams) => any): IMethod;
249
/** Create event in this namespace */
250
event(ev_name: string): IEvent;
251
/** Get list of events in this namespace */
252
readonly eventList: string[];
253
/** Emit event to this namespace */
254
emit(event: string, ...params: Array<string>): void;
255
/** Get namespace name */
256
readonly name: string;
257
/** Get connected clients in this namespace */
258
connected(): {};
259
/** Get namespace client data */
260
clients(): {
261
rpc_methods: IRPCMethod;
262
clients: Map<string, IClientWebSocket>;
263
events: INamespaceEvent;
264
};
265
};
266
267
/**
268
* Removes a namespace and closes all connections
269
* @param ns - namespace identifier
270
*/
271
closeNamespace(ns: string): void;
272
```
273
274
**Usage Examples:**
275
276
```typescript
277
// Work with admin namespace
278
const adminNS = server.of("/admin");
279
280
// Register methods in namespace
281
adminNS.register("restart", () => {
282
return { status: "restarting" };
283
});
284
285
adminNS.register("getStats", () => {
286
return { users: 100, uptime: "2 days" };
287
});
288
289
// Create events in namespace
290
adminNS.event("systemAlert");
291
292
// Emit to namespace
293
adminNS.emit("systemAlert", "High memory usage detected");
294
295
// Get namespace info
296
console.log("Admin namespace events:", adminNS.eventList);
297
console.log("Connected admin clients:", Object.keys(adminNS.connected()));
298
299
// Close namespace when done
300
server.closeNamespace("/admin");
301
```
302
303
### Error Handling
304
305
Create JSON-RPC 2.0 compliant error responses and handle server errors.
306
307
```typescript { .api }
308
/**
309
* Creates a JSON-RPC 2.0 compliant error
310
* @param code - indicates the error type that occurred
311
* @param message - provides a short description of the error
312
* @param data - details containing additional information about the error
313
* @returns JSON-RPC error object
314
*/
315
createError(code: number, message: string, data: string | object): {
316
code: number;
317
message: string;
318
data: string | object;
319
};
320
```
321
322
**Standard JSON-RPC Error Codes:**
323
- `-32700`: Parse error
324
- `-32600`: Invalid Request
325
- `-32601`: Method not found
326
- `-32602`: Invalid params
327
- `-32603`: Internal error
328
- `-32000`: Event not provided
329
- `-32604`: Params not found
330
- `-32605`: Method forbidden
331
- `-32606`: Event forbidden
332
333
**Usage Examples:**
334
335
```typescript
336
// Method that returns custom error
337
server.register("validateData", (params) => {
338
if (!params.email) {
339
throw server.createError(-32602, "Invalid params", "Email is required");
340
}
341
342
if (!params.email.includes("@")) {
343
throw server.createError(-32000, "Validation failed", "Invalid email format");
344
}
345
346
return { valid: true };
347
});
348
349
// Handle server errors
350
server.on("error", (error) => {
351
console.error("Server error:", error);
352
});
353
354
// Handle socket errors
355
server.on("socket-error", (socket, error) => {
356
console.error(`Socket ${socket._id} error:`, error);
357
});
358
```
359
360
### Server Lifecycle
361
362
Control server startup, shutdown, and connection handling.
363
364
```typescript { .api }
365
/**
366
* Closes the server and terminates all clients
367
* @returns Promise resolving when server is closed
368
*/
369
close(): Promise<void>;
370
```
371
372
**Usage Examples:**
373
374
```typescript
375
// Server lifecycle events
376
server.on("listening", () => {
377
console.log("Server listening on port 8080");
378
});
379
380
server.on("connection", (socket, request) => {
381
console.log(`New connection: ${socket._id}`);
382
console.log(`URL: ${request.url}`);
383
});
384
385
server.on("disconnection", (socket) => {
386
console.log(`Client disconnected: ${socket._id}`);
387
});
388
389
// Graceful shutdown
390
process.on("SIGTERM", async () => {
391
console.log("Shutting down server...");
392
await server.close();
393
process.exit(0);
394
});
395
```
396
397
## Server Interface Types
398
399
```typescript { .api }
400
interface IRPCMethod {
401
[x: string]: {
402
fn: (params: IRPCMethodParams, socket_id: string) => any;
403
protected: boolean;
404
};
405
}
406
407
interface INamespaceEvent {
408
[x: string]: {
409
sockets: Array<string>;
410
protected: boolean;
411
};
412
}
413
414
interface IClientWebSocket extends NodeWebSocket {
415
_id: string;
416
_authenticated: boolean;
417
}
418
419
interface IRPCError {
420
code: number;
421
message: string;
422
data?: string;
423
}
424
```
425
426
## Server Events
427
428
The server emits the following events during its lifecycle:
429
430
- **`listening`**: Fired when server starts listening for connections
431
- **`connection`**: Fired when a new client connects (socket, request)
432
- **`disconnection`**: Fired when a client disconnects (socket)
433
- **`error`**: Fired when server errors occur (error)
434
- **`socket-error`**: Fired when individual socket errors occur (socket, error)
435
- **`close`**: Fired when server is closed