UNPKG

18.8 kBTypeScriptView Raw
1/// <reference types="node" />
2/// <reference types="node" />
3/// <reference types="node" />
4import http = require("http");
5import type { Server as HTTPSServer } from "https";
6import type { Http2SecureServer, Http2Server } from "http2";
7import type { ServerOptions as EngineOptions, AttachOptions, BaseServer } from "engine.io";
8import { ExtendedError, Namespace, ServerReservedEventsMap } from "./namespace";
9import { Adapter, Room, SocketId } from "socket.io-adapter";
10import * as parser from "socket.io-parser";
11import type { Encoder } from "socket.io-parser";
12import { Socket, DisconnectReason } from "./socket";
13import type { BroadcastOperator, RemoteSocket } from "./broadcast-operator";
14import { EventsMap, DefaultEventsMap, EventParams, StrictEventEmitter, EventNames, DecorateAcknowledgementsWithTimeoutAndMultipleResponses, AllButLast, Last, RemoveAcknowledgements, EventNamesWithAck, FirstNonErrorArg } from "./typed-events";
15declare type ParentNspNameMatchFn = (name: string, auth: {
16 [key: string]: any;
17}, fn: (err: Error | null, success: boolean) => void) => void;
18declare type AdapterConstructor = typeof Adapter | ((nsp: Namespace) => Adapter);
19declare type TServerInstance = http.Server | HTTPSServer | Http2SecureServer | Http2Server;
20interface 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 */
97export 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}
525export { Socket, DisconnectReason, ServerOptions, Namespace, BroadcastOperator, RemoteSocket, };
526export { Event } from "./socket";
527
\No newline at end of file