1 | /// <reference types="node" />
|
2 | /// <reference types="node" />
|
3 | /// <reference types="node" />
|
4 | import http = require("http");
|
5 | import type { Server as HTTPSServer } from "https";
|
6 | import type { Http2SecureServer, Http2Server } from "http2";
|
7 | import type { ServerOptions as EngineOptions, AttachOptions, BaseServer } from "engine.io";
|
8 | import { ExtendedError, Namespace, ServerReservedEventsMap } from "./namespace";
|
9 | import { Adapter, Room, SocketId } from "socket.io-adapter";
|
10 | import * as parser from "socket.io-parser";
|
11 | import type { Encoder } from "socket.io-parser";
|
12 | import { Socket, DisconnectReason } from "./socket";
|
13 | import type { BroadcastOperator, RemoteSocket } from "./broadcast-operator";
|
14 | import { EventsMap, DefaultEventsMap, EventParams, StrictEventEmitter, EventNames, DecorateAcknowledgementsWithTimeoutAndMultipleResponses, AllButLast, Last, RemoveAcknowledgements, EventNamesWithAck, FirstNonErrorArg } from "./typed-events";
|
15 | declare type ParentNspNameMatchFn = (name: string, auth: {
|
16 | [key: string]: any;
|
17 | }, fn: (err: Error | null, success: boolean) => void) => void;
|
18 | declare type AdapterConstructor = typeof Adapter | ((nsp: Namespace) => Adapter);
|
19 | declare type TServerInstance = http.Server | HTTPSServer | Http2SecureServer | Http2Server;
|
20 | interface ServerOptions extends EngineOptions, AttachOptions {
|
21 | /**
|
22 | * name of the path to capture
|
23 | * @default "/socket.io"
|
24 | */
|
25 | path: string;
|
26 | /**
|
27 | * whether to serve the client files
|
28 | * @default true
|
29 | */
|
30 | serveClient: boolean;
|
31 | /**
|
32 | * the adapter to use
|
33 | * @default the in-memory adapter (https://github.com/socketio/socket.io-adapter)
|
34 | */
|
35 | adapter: AdapterConstructor;
|
36 | /**
|
37 | * the parser to use
|
38 | * @default the default parser (https://github.com/socketio/socket.io-parser)
|
39 | */
|
40 | parser: any;
|
41 | /**
|
42 | * how many ms before a client without namespace is closed
|
43 | * @default 45000
|
44 | */
|
45 | connectTimeout: number;
|
46 | /**
|
47 | * Whether to enable the recovery of connection state when a client temporarily disconnects.
|
48 | *
|
49 | * The connection state includes the missed packets, the rooms the socket was in and the `data` attribute.
|
50 | */
|
51 | connectionStateRecovery: {
|
52 | /**
|
53 | * The backup duration of the sessions and the packets.
|
54 | *
|
55 | * @default 120000 (2 minutes)
|
56 | */
|
57 | maxDisconnectionDuration?: number;
|
58 | /**
|
59 | * Whether to skip middlewares upon successful connection state recovery.
|
60 | *
|
61 | * @default true
|
62 | */
|
63 | skipMiddlewares?: boolean;
|
64 | };
|
65 | /**
|
66 | * Whether to remove child namespaces that have no sockets connected to them
|
67 | * @default false
|
68 | */
|
69 | cleanupEmptyChildNamespaces: boolean;
|
70 | }
|
71 | /**
|
72 | * Represents a Socket.IO server.
|
73 | *
|
74 | * @example
|
75 | * import { Server } from "socket.io";
|
76 | *
|
77 | * const io = new Server();
|
78 | *
|
79 | * io.on("connection", (socket) => {
|
80 | * console.log(`socket ${socket.id} connected`);
|
81 | *
|
82 | * // send an event to the client
|
83 | * socket.emit("foo", "bar");
|
84 | *
|
85 | * socket.on("foobar", () => {
|
86 | * // an event was received from the client
|
87 | * });
|
88 | *
|
89 | * // upon disconnection
|
90 | * socket.on("disconnect", (reason) => {
|
91 | * console.log(`socket ${socket.id} disconnected due to ${reason}`);
|
92 | * });
|
93 | * });
|
94 | *
|
95 | * io.listen(3000);
|
96 | */
|
97 | export declare class Server<ListenEvents extends EventsMap = DefaultEventsMap, EmitEvents extends EventsMap = ListenEvents, ServerSideEvents extends EventsMap = DefaultEventsMap, SocketData = any> extends StrictEventEmitter<ServerSideEvents, RemoveAcknowledgements<EmitEvents>, ServerReservedEventsMap<ListenEvents, EmitEvents, ServerSideEvents, SocketData>> {
|
98 | readonly sockets: Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>;
|
99 | /**
|
100 | * A reference to the underlying Engine.IO server.
|
101 | *
|
102 | * @example
|
103 | * const clientsCount = io.engine.clientsCount;
|
104 | *
|
105 | */
|
106 | engine: BaseServer;
|
107 | /** @private */
|
108 | readonly _parser: typeof parser;
|
109 | /** @private */
|
110 | readonly encoder: Encoder;
|
111 | /**
|
112 | * @private
|
113 | */
|
114 | _nsps: Map<string, Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>>;
|
115 | private parentNsps;
|
116 | /**
|
117 | * A subset of the {@link parentNsps} map, only containing {@link ParentNamespace} which are based on a regular
|
118 | * expression.
|
119 | *
|
120 | * @private
|
121 | */
|
122 | private parentNamespacesFromRegExp;
|
123 | private _adapter?;
|
124 | private _serveClient;
|
125 | private readonly opts;
|
126 | private eio;
|
127 | private _path;
|
128 | private clientPathRegex;
|
129 | /**
|
130 | * @private
|
131 | */
|
132 | _connectTimeout: number;
|
133 | private httpServer;
|
134 | private _corsMiddleware;
|
135 | /**
|
136 | * Server constructor.
|
137 | *
|
138 | * @param srv http server, port, or options
|
139 | * @param [opts]
|
140 | */
|
141 | constructor(opts?: Partial<ServerOptions>);
|
142 | constructor(srv?: TServerInstance | number, opts?: Partial<ServerOptions>);
|
143 | constructor(srv: undefined | Partial<ServerOptions> | TServerInstance | number, opts?: Partial<ServerOptions>);
|
144 | get _opts(): Partial<ServerOptions>;
|
145 | /**
|
146 | * Sets/gets whether client code is being served.
|
147 | *
|
148 | * @param v - whether to serve client code
|
149 | * @return self when setting or value when getting
|
150 | */
|
151 | serveClient(v: boolean): this;
|
152 | serveClient(): boolean;
|
153 | serveClient(v?: boolean): this | boolean;
|
154 | /**
|
155 | * Executes the middleware for an incoming namespace not already created on the server.
|
156 | *
|
157 | * @param name - name of incoming namespace
|
158 | * @param auth - the auth parameters
|
159 | * @param fn - callback
|
160 | *
|
161 | * @private
|
162 | */
|
163 | _checkNamespace(name: string, auth: {
|
164 | [key: string]: any;
|
165 | }, fn: (nsp: Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData> | false) => void): void;
|
166 | /**
|
167 | * Sets the client serving path.
|
168 | *
|
169 | * @param {String} v pathname
|
170 | * @return {Server|String} self when setting or value when getting
|
171 | */
|
172 | path(v: string): this;
|
173 | path(): string;
|
174 | path(v?: string): this | string;
|
175 | /**
|
176 | * Set the delay after which a client without namespace is closed
|
177 | * @param v
|
178 | */
|
179 | connectTimeout(v: number): this;
|
180 | connectTimeout(): number;
|
181 | connectTimeout(v?: number): this | number;
|
182 | /**
|
183 | * Sets the adapter for rooms.
|
184 | *
|
185 | * @param v pathname
|
186 | * @return self when setting or value when getting
|
187 | */
|
188 | adapter(): AdapterConstructor | undefined;
|
189 | adapter(v: AdapterConstructor): this;
|
190 | /**
|
191 | * Attaches socket.io to a server or port.
|
192 | *
|
193 | * @param srv - server or port
|
194 | * @param opts - options passed to engine.io
|
195 | * @return self
|
196 | */
|
197 | listen(srv: TServerInstance | number, opts?: Partial<ServerOptions>): this;
|
198 | /**
|
199 | * Attaches socket.io to a server or port.
|
200 | *
|
201 | * @param srv - server or port
|
202 | * @param opts - options passed to engine.io
|
203 | * @return self
|
204 | */
|
205 | attach(srv: TServerInstance | number, opts?: Partial<ServerOptions>): this;
|
206 | attachApp(app: any, opts?: Partial<ServerOptions>): void;
|
207 | /**
|
208 | * Initialize engine
|
209 | *
|
210 | * @param srv - the server to attach to
|
211 | * @param opts - options passed to engine.io
|
212 | * @private
|
213 | */
|
214 | private initEngine;
|
215 | /**
|
216 | * Attaches the static file serving.
|
217 | *
|
218 | * @param srv http server
|
219 | * @private
|
220 | */
|
221 | private attachServe;
|
222 | /**
|
223 | * Handles a request serving of client source and map
|
224 | *
|
225 | * @param req
|
226 | * @param res
|
227 | * @private
|
228 | */
|
229 | private serve;
|
230 | /**
|
231 | * @param filename
|
232 | * @param req
|
233 | * @param res
|
234 | * @private
|
235 | */
|
236 | private static sendFile;
|
237 | /**
|
238 | * Binds socket.io to an engine.io instance.
|
239 | *
|
240 | * @param engine engine.io (or compatible) server
|
241 | * @return self
|
242 | */
|
243 | bind(engine: BaseServer): this;
|
244 | /**
|
245 | * Called with each incoming transport connection.
|
246 | *
|
247 | * @param {engine.Socket} conn
|
248 | * @return self
|
249 | * @private
|
250 | */
|
251 | private onconnection;
|
252 | /**
|
253 | * Looks up a namespace.
|
254 | *
|
255 | * @example
|
256 | * // with a simple string
|
257 | * const myNamespace = io.of("/my-namespace");
|
258 | *
|
259 | * // with a regex
|
260 | * const dynamicNsp = io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
|
261 | * const namespace = socket.nsp; // newNamespace.name === "/dynamic-101"
|
262 | *
|
263 | * // broadcast to all clients in the given sub-namespace
|
264 | * namespace.emit("hello");
|
265 | * });
|
266 | *
|
267 | * @param name - nsp name
|
268 | * @param fn optional, nsp `connection` ev handler
|
269 | */
|
270 | of(name: string | RegExp | ParentNspNameMatchFn, fn?: (socket: Socket<ListenEvents, EmitEvents, ServerSideEvents, SocketData>) => void): Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>;
|
271 | /**
|
272 | * Closes server connection
|
273 | *
|
274 | * @param [fn] optional, called as `fn([err])` on error OR all conns closed
|
275 | */
|
276 | close(fn?: (err?: Error) => void): void;
|
277 | /**
|
278 | * Registers a middleware, which is a function that gets executed for every incoming {@link Socket}.
|
279 | *
|
280 | * @example
|
281 | * io.use((socket, next) => {
|
282 | * // ...
|
283 | * next();
|
284 | * });
|
285 | *
|
286 | * @param fn - the middleware function
|
287 | */
|
288 | use(fn: (socket: Socket<ListenEvents, EmitEvents, ServerSideEvents, SocketData>, next: (err?: ExtendedError) => void) => void): this;
|
289 | /**
|
290 | * Targets a room when emitting.
|
291 | *
|
292 | * @example
|
293 | * // the “foo” event will be broadcast to all connected clients in the “room-101” room
|
294 | * io.to("room-101").emit("foo", "bar");
|
295 | *
|
296 | * // with an array of rooms (a client will be notified at most once)
|
297 | * io.to(["room-101", "room-102"]).emit("foo", "bar");
|
298 | *
|
299 | * // with multiple chained calls
|
300 | * io.to("room-101").to("room-102").emit("foo", "bar");
|
301 | *
|
302 | * @param room - a room, or an array of rooms
|
303 | * @return a new {@link BroadcastOperator} instance for chaining
|
304 | */
|
305 | to(room: Room | Room[]): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
306 | /**
|
307 | * Targets a room when emitting. Similar to `to()`, but might feel clearer in some cases:
|
308 | *
|
309 | * @example
|
310 | * // disconnect all clients in the "room-101" room
|
311 | * io.in("room-101").disconnectSockets();
|
312 | *
|
313 | * @param room - a room, or an array of rooms
|
314 | * @return a new {@link BroadcastOperator} instance for chaining
|
315 | */
|
316 | in(room: Room | Room[]): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
317 | /**
|
318 | * Excludes a room when emitting.
|
319 | *
|
320 | * @example
|
321 | * // the "foo" event will be broadcast to all connected clients, except the ones that are in the "room-101" room
|
322 | * io.except("room-101").emit("foo", "bar");
|
323 | *
|
324 | * // with an array of rooms
|
325 | * io.except(["room-101", "room-102"]).emit("foo", "bar");
|
326 | *
|
327 | * // with multiple chained calls
|
328 | * io.except("room-101").except("room-102").emit("foo", "bar");
|
329 | *
|
330 | * @param room - a room, or an array of rooms
|
331 | * @return a new {@link BroadcastOperator} instance for chaining
|
332 | */
|
333 | except(room: Room | Room[]): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
334 | /**
|
335 | * Sends a `message` event to all clients.
|
336 | *
|
337 | * This method mimics the WebSocket.send() method.
|
338 | *
|
339 | * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
340 | *
|
341 | * @example
|
342 | * io.send("hello");
|
343 | *
|
344 | * // this is equivalent to
|
345 | * io.emit("message", "hello");
|
346 | *
|
347 | * @return self
|
348 | */
|
349 | send(...args: EventParams<EmitEvents, "message">): this;
|
350 | /**
|
351 | * Sends a `message` event to all clients. Alias of {@link send}.
|
352 | *
|
353 | * @return self
|
354 | */
|
355 | write(...args: EventParams<EmitEvents, "message">): this;
|
356 | /**
|
357 | * Sends a message to the other Socket.IO servers of the cluster.
|
358 | *
|
359 | * @example
|
360 | * io.serverSideEmit("hello", "world");
|
361 | *
|
362 | * io.on("hello", (arg1) => {
|
363 | * console.log(arg1); // prints "world"
|
364 | * });
|
365 | *
|
366 | * // acknowledgements (without binary content) are supported too:
|
367 | * io.serverSideEmit("ping", (err, responses) => {
|
368 | * if (err) {
|
369 | * // some servers did not acknowledge the event in the given delay
|
370 | * } else {
|
371 | * console.log(responses); // one response per server (except the current one)
|
372 | * }
|
373 | * });
|
374 | *
|
375 | * io.on("ping", (cb) => {
|
376 | * cb("pong");
|
377 | * });
|
378 | *
|
379 | * @param ev - the event name
|
380 | * @param args - an array of arguments, which may include an acknowledgement callback at the end
|
381 | */
|
382 | serverSideEmit<Ev extends EventNames<ServerSideEvents>>(ev: Ev, ...args: EventParams<DecorateAcknowledgementsWithTimeoutAndMultipleResponses<ServerSideEvents>, Ev>): boolean;
|
383 | /**
|
384 | * Sends a message and expect an acknowledgement from the other Socket.IO servers of the cluster.
|
385 | *
|
386 | * @example
|
387 | * try {
|
388 | * const responses = await io.serverSideEmitWithAck("ping");
|
389 | * console.log(responses); // one response per server (except the current one)
|
390 | * } catch (e) {
|
391 | * // some servers did not acknowledge the event in the given delay
|
392 | * }
|
393 | *
|
394 | * @param ev - the event name
|
395 | * @param args - an array of arguments
|
396 | *
|
397 | * @return a Promise that will be fulfilled when all servers have acknowledged the event
|
398 | */
|
399 | serverSideEmitWithAck<Ev extends EventNamesWithAck<ServerSideEvents>>(ev: Ev, ...args: AllButLast<EventParams<ServerSideEvents, Ev>>): Promise<FirstNonErrorArg<Last<EventParams<ServerSideEvents, Ev>>>[]>;
|
400 | /**
|
401 | * Gets a list of socket ids.
|
402 | *
|
403 | * @deprecated this method will be removed in the next major release, please use {@link Server#serverSideEmit} or
|
404 | * {@link Server#fetchSockets} instead.
|
405 | */
|
406 | allSockets(): Promise<Set<SocketId>>;
|
407 | /**
|
408 | * Sets the compress flag.
|
409 | *
|
410 | * @example
|
411 | * io.compress(false).emit("hello");
|
412 | *
|
413 | * @param compress - if `true`, compresses the sending data
|
414 | * @return a new {@link BroadcastOperator} instance for chaining
|
415 | */
|
416 | compress(compress: boolean): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
417 | /**
|
418 | * Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
|
419 | * receive messages (because of network slowness or other issues, or because they’re connected through long polling
|
420 | * and is in the middle of a request-response cycle).
|
421 | *
|
422 | * @example
|
423 | * io.volatile.emit("hello"); // the clients may or may not receive it
|
424 | *
|
425 | * @return a new {@link BroadcastOperator} instance for chaining
|
426 | */
|
427 | get volatile(): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
428 | /**
|
429 | * Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
|
430 | *
|
431 | * @example
|
432 | * // the “foo” event will be broadcast to all connected clients on this node
|
433 | * io.local.emit("foo", "bar");
|
434 | *
|
435 | * @return a new {@link BroadcastOperator} instance for chaining
|
436 | */
|
437 | get local(): BroadcastOperator<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>, SocketData>;
|
438 | /**
|
439 | * Adds a timeout in milliseconds for the next operation.
|
440 | *
|
441 | * @example
|
442 | * io.timeout(1000).emit("some-event", (err, responses) => {
|
443 | * if (err) {
|
444 | * // some clients did not acknowledge the event in the given delay
|
445 | * } else {
|
446 | * console.log(responses); // one response per client
|
447 | * }
|
448 | * });
|
449 | *
|
450 | * @param timeout
|
451 | */
|
452 | timeout(timeout: number): BroadcastOperator<import("./typed-events").DecorateAcknowledgements<import("./typed-events").DecorateAcknowledgementsWithMultipleResponses<EmitEvents>>, SocketData>;
|
453 | /**
|
454 | * Returns the matching socket instances.
|
455 | *
|
456 | * Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
|
457 | *
|
458 | * @example
|
459 | * // return all Socket instances
|
460 | * const sockets = await io.fetchSockets();
|
461 | *
|
462 | * // return all Socket instances in the "room1" room
|
463 | * const sockets = await io.in("room1").fetchSockets();
|
464 | *
|
465 | * for (const socket of sockets) {
|
466 | * console.log(socket.id);
|
467 | * console.log(socket.handshake);
|
468 | * console.log(socket.rooms);
|
469 | * console.log(socket.data);
|
470 | *
|
471 | * socket.emit("hello");
|
472 | * socket.join("room1");
|
473 | * socket.leave("room2");
|
474 | * socket.disconnect();
|
475 | * }
|
476 | */
|
477 | fetchSockets(): Promise<RemoteSocket<EmitEvents, SocketData>[]>;
|
478 | /**
|
479 | * Makes the matching socket instances join the specified rooms.
|
480 | *
|
481 | * Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
|
482 | *
|
483 | * @example
|
484 | *
|
485 | * // make all socket instances join the "room1" room
|
486 | * io.socketsJoin("room1");
|
487 | *
|
488 | * // make all socket instances in the "room1" room join the "room2" and "room3" rooms
|
489 | * io.in("room1").socketsJoin(["room2", "room3"]);
|
490 | *
|
491 | * @param room - a room, or an array of rooms
|
492 | */
|
493 | socketsJoin(room: Room | Room[]): void;
|
494 | /**
|
495 | * Makes the matching socket instances leave the specified rooms.
|
496 | *
|
497 | * Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
|
498 | *
|
499 | * @example
|
500 | * // make all socket instances leave the "room1" room
|
501 | * io.socketsLeave("room1");
|
502 | *
|
503 | * // make all socket instances in the "room1" room leave the "room2" and "room3" rooms
|
504 | * io.in("room1").socketsLeave(["room2", "room3"]);
|
505 | *
|
506 | * @param room - a room, or an array of rooms
|
507 | */
|
508 | socketsLeave(room: Room | Room[]): void;
|
509 | /**
|
510 | * Makes the matching socket instances disconnect.
|
511 | *
|
512 | * Note: this method also works within a cluster of multiple Socket.IO servers, with a compatible {@link Adapter}.
|
513 | *
|
514 | * @example
|
515 | * // make all socket instances disconnect (the connections might be kept alive for other namespaces)
|
516 | * io.disconnectSockets();
|
517 | *
|
518 | * // make all socket instances in the "room1" room disconnect and close the underlying connections
|
519 | * io.in("room1").disconnectSockets(true);
|
520 | *
|
521 | * @param close - whether to close the underlying connection
|
522 | */
|
523 | disconnectSockets(close?: boolean): void;
|
524 | }
|
525 | export { Socket, DisconnectReason, ServerOptions, Namespace, BroadcastOperator, RemoteSocket, };
|
526 | export { Event } from "./socket";
|
527 |
|
\ | No newline at end of file |