Files
socket.io/lib/parent-namespace.ts
Damien Arrachequesne 93cce05fb3 feat: add support for inter-server communication
Syntax:

```js
// server A
io.serverSideEmit("hello", "world");

// server B
io.on("hello", (arg) => {
  console.log(arg); // prints "world"
});
```

With acknowledgements:

```js
// server A
io.serverSideEmit("hello", "world", (err, responses) => {
  console.log(responses); // prints ["hi"]
});

// server B
io.on("hello", (arg, callback) => {
  callback("hi");
});
```

This feature replaces the customHook/customRequest API from the Redis
adapter: https://github.com/socketio/socket.io-redis/issues/370
2021-05-11 00:07:20 +02:00

65 lines
1.8 KiB
TypeScript

import { Namespace } from "./namespace";
import type { Server } from "./index";
import type {
EventParams,
EventNames,
EventsMap,
DefaultEventsMap,
} from "./typed-events";
import type { BroadcastOptions } from "socket.io-adapter";
export class ParentNamespace<
ListenEvents extends EventsMap = DefaultEventsMap,
EmitEvents extends EventsMap = ListenEvents,
ServerSideEvents extends EventsMap = {}
> extends Namespace<ListenEvents, EmitEvents, ServerSideEvents> {
private static count: number = 0;
private children: Set<
Namespace<ListenEvents, EmitEvents, ServerSideEvents>
> = new Set();
constructor(server: Server<ListenEvents, EmitEvents, ServerSideEvents>) {
super(server, "/_" + ParentNamespace.count++);
}
/**
* @private
*/
_initAdapter(): void {
const broadcast = (packet: any, opts: BroadcastOptions) => {
this.children.forEach((nsp) => {
nsp.adapter.broadcast(packet, opts);
});
};
// @ts-ignore FIXME is there a way to declare an inner class in TypeScript?
this.adapter = { broadcast };
}
public emit<Ev extends EventNames<EmitEvents>>(
ev: Ev,
...args: EventParams<EmitEvents, Ev>
): boolean {
this.children.forEach((nsp) => {
nsp.emit(ev, ...args);
});
return true;
}
createChild(
name: string
): Namespace<ListenEvents, EmitEvents, ServerSideEvents> {
const namespace = new Namespace(this.server, name);
namespace._fns = this._fns.slice(0);
this.listeners("connect").forEach((listener) =>
namespace.on("connect", listener)
);
this.listeners("connection").forEach((listener) =>
namespace.on("connection", listener)
);
this.children.add(namespace);
this.server._nsps.set(name, namespace);
return namespace;
}
}