Skip to content

Commit 499c892

Browse files
feat: notify upon namespace creation
A "new_namespace" event will be emitted when a new namespace is created: ```js io.on("new_namespace", (namespace) => { // ... }); ``` This could be used for example for registering the same middleware for each namespace. See #3851
1 parent 93cce05 commit 499c892

File tree

3 files changed

+58
-10
lines changed

3 files changed

+58
-10
lines changed

lib/index.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ import path = require("path");
77
import engine = require("engine.io");
88
import { Client } from "./client";
99
import { EventEmitter } from "events";
10-
import {
11-
ExtendedError,
12-
Namespace,
13-
NamespaceReservedEventsMap,
14-
} from "./namespace";
10+
import { ExtendedError, Namespace, ServerReservedEventsMap } from "./namespace";
1511
import { ParentNamespace } from "./parent-namespace";
1612
import { Adapter, Room, SocketId } from "socket.io-adapter";
1713
import * as parser from "socket.io-parser";
@@ -176,7 +172,7 @@ export class Server<
176172
> extends StrictEventEmitter<
177173
ServerSideEvents,
178174
EmitEvents,
179-
NamespaceReservedEventsMap<ListenEvents, EmitEvents, ServerSideEvents>
175+
ServerReservedEventsMap<ListenEvents, EmitEvents, ServerSideEvents>
180176
> {
181177
public readonly sockets: Namespace<
182178
ListenEvents,
@@ -306,7 +302,12 @@ export class Server<
306302
if (err || !allow) {
307303
run();
308304
} else {
309-
fn(this.parentNsps.get(nextFn.value)!.createChild(name));
305+
const namespace = this.parentNsps
306+
.get(nextFn.value)!
307+
.createChild(name);
308+
// @ts-ignore
309+
this.sockets.emitReserved("new_namespace", namespace);
310+
fn(namespace);
310311
}
311312
});
312313
};
@@ -627,6 +628,10 @@ export class Server<
627628
debug("initializing namespace %s", name);
628629
nsp = new Namespace(this, name);
629630
this._nsps.set(name, nsp);
631+
if (name !== "/") {
632+
// @ts-ignore
633+
this.sockets.emitReserved("new_namespace", nsp);
634+
}
630635
}
631636
if (fn) nsp.on("connect", fn);
632637
return nsp;

lib/namespace.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,23 @@ export interface NamespaceReservedEventsMap<
2929
) => void;
3030
}
3131

32+
export interface ServerReservedEventsMap<
33+
ListenEvents,
34+
EmitEvents,
35+
ServerSideEvents
36+
> extends NamespaceReservedEventsMap<
37+
ListenEvents,
38+
EmitEvents,
39+
ServerSideEvents
40+
> {
41+
new_namespace: (
42+
namespace: Namespace<ListenEvents, EmitEvents, ServerSideEvents>
43+
) => void;
44+
}
45+
3246
export const RESERVED_EVENTS: ReadonlySet<string | Symbol> = new Set<
33-
keyof NamespaceReservedEventsMap<never, never, never>
34-
>(<const>["connect", "connection"]);
47+
keyof ServerReservedEventsMap<never, never, never>
48+
>(<const>["connect", "connection", "new_namespace"]);
3549

3650
export class Namespace<
3751
ListenEvents extends EventsMap = DefaultEventsMap,

test/socket.io.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ describe("socket.io", () => {
812812
});
813813
});
814814

815-
it("should close a client without namespace", (done) => {
815+
it("should close a client without namespace (2)", (done) => {
816816
const srv = createServer();
817817
const sio = new Server(srv, {
818818
connectTimeout: 100,
@@ -886,6 +886,17 @@ describe("socket.io", () => {
886886
});
887887
});
888888

889+
it("should emit an 'new_namespace' event", (done) => {
890+
const sio = new Server();
891+
892+
sio.on("new_namespace", (namespace) => {
893+
expect(namespace.name).to.eql("/nsp");
894+
done();
895+
});
896+
897+
sio.of("/nsp");
898+
});
899+
889900
describe("dynamic namespaces", () => {
890901
it("should allow connections to dynamic namespaces with a regex", (done) => {
891902
const srv = createServer();
@@ -942,6 +953,24 @@ describe("socket.io", () => {
942953
});
943954
});
944955
});
956+
957+
it("should emit an 'new_namespace' event for a dynamic namespace", (done) => {
958+
const srv = createServer();
959+
const sio = new Server(srv);
960+
srv.listen(() => {
961+
sio.of(/^\/dynamic-\d+$/);
962+
963+
sio.on("new_namespace", (namespace) => {
964+
expect(namespace.name).to.be("/dynamic-101");
965+
966+
socket.disconnect();
967+
srv.close();
968+
done();
969+
});
970+
971+
const socket = client(srv, "/dynamic-101");
972+
});
973+
});
945974
});
946975
});
947976

0 commit comments

Comments
 (0)