parent-namespace.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.ParentNamespace = void 0;
  7. const namespace_1 = require("./namespace");
  8. const debug_1 = __importDefault(require("debug"));
  9. const debug = (0, debug_1.default)("socket.io:parent-namespace");
  10. /**
  11. * A parent namespace is a special {@link Namespace} that holds a list of child namespaces which were created either
  12. * with a regular expression or with a function.
  13. *
  14. * @example
  15. * const parentNamespace = io.of(/\/dynamic-\d+/);
  16. *
  17. * parentNamespace.on("connection", (socket) => {
  18. * const childNamespace = socket.nsp;
  19. * }
  20. *
  21. * // will reach all the clients that are in one of the child namespaces, like "/dynamic-101"
  22. * parentNamespace.emit("hello", "world");
  23. *
  24. */
  25. class ParentNamespace extends namespace_1.Namespace {
  26. constructor(server) {
  27. super(server, "/_" + ParentNamespace.count++);
  28. this.children = new Set();
  29. }
  30. /**
  31. * @private
  32. */
  33. _initAdapter() {
  34. const broadcast = (packet, opts) => {
  35. this.children.forEach((nsp) => {
  36. nsp.adapter.broadcast(packet, opts);
  37. });
  38. };
  39. // @ts-ignore FIXME is there a way to declare an inner class in TypeScript?
  40. this.adapter = { broadcast };
  41. }
  42. emit(ev, ...args) {
  43. this.children.forEach((nsp) => {
  44. nsp.emit(ev, ...args);
  45. });
  46. return true;
  47. }
  48. createChild(name) {
  49. debug("creating child namespace %s", name);
  50. const namespace = new namespace_1.Namespace(this.server, name);
  51. namespace._fns = this._fns.slice(0);
  52. this.listeners("connect").forEach((listener) => namespace.on("connect", listener));
  53. this.listeners("connection").forEach((listener) => namespace.on("connection", listener));
  54. this.children.add(namespace);
  55. if (this.server._opts.cleanupEmptyChildNamespaces) {
  56. const remove = namespace._remove;
  57. namespace._remove = (socket) => {
  58. remove.call(namespace, socket);
  59. if (namespace.sockets.size === 0) {
  60. debug("closing child namespace %s", name);
  61. namespace.adapter.close();
  62. this.server._nsps.delete(namespace.name);
  63. this.children.delete(namespace);
  64. }
  65. };
  66. }
  67. this.server._nsps.set(name, namespace);
  68. // @ts-ignore
  69. this.server.sockets.emitReserved("new_namespace", namespace);
  70. return namespace;
  71. }
  72. fetchSockets() {
  73. // note: we could make the fetchSockets() method work for dynamic namespaces created with a regex (by sending the
  74. // regex to the other Socket.IO servers, and returning the sockets of each matching namespace for example), but
  75. // the behavior for namespaces created with a function is less clear
  76. // note²: we cannot loop over each children namespace, because with multiple Socket.IO servers, a given namespace
  77. // may exist on one node but not exist on another (since it is created upon client connection)
  78. throw new Error("fetchSockets() is not supported on parent namespaces");
  79. }
  80. }
  81. exports.ParentNamespace = ParentNamespace;
  82. ParentNamespace.count = 0;