UNPKG

8.43 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Namespace = exports.RESERVED_EVENTS = void 0;
7const socket_1 = require("./socket");
8const typed_events_1 = require("./typed-events");
9const debug_1 = __importDefault(require("debug"));
10const broadcast_operator_1 = require("./broadcast-operator");
11const debug = (0, debug_1.default)("socket.io:namespace");
12exports.RESERVED_EVENTS = new Set(["connect", "connection", "new_namespace"]);
13class Namespace extends typed_events_1.StrictEventEmitter {
14 /**
15 * Namespace constructor.
16 *
17 * @param server instance
18 * @param name
19 */
20 constructor(server, name) {
21 super();
22 this.sockets = new Map();
23 /** @private */
24 this._fns = [];
25 /** @private */
26 this._ids = 0;
27 this.server = server;
28 this.name = name;
29 this._initAdapter();
30 }
31 /**
32 * Initializes the `Adapter` for this nsp.
33 * Run upon changing adapter by `Server#adapter`
34 * in addition to the constructor.
35 *
36 * @private
37 */
38 _initAdapter() {
39 // @ts-ignore
40 this.adapter = new (this.server.adapter())(this);
41 }
42 /**
43 * Sets up namespace middleware.
44 *
45 * @return self
46 * @public
47 */
48 use(fn) {
49 this._fns.push(fn);
50 return this;
51 }
52 /**
53 * Executes the middleware for an incoming client.
54 *
55 * @param socket - the socket that will get added
56 * @param fn - last fn call in the middleware
57 * @private
58 */
59 run(socket, fn) {
60 const fns = this._fns.slice(0);
61 if (!fns.length)
62 return fn(null);
63 function run(i) {
64 fns[i](socket, function (err) {
65 // upon error, short-circuit
66 if (err)
67 return fn(err);
68 // if no middleware left, summon callback
69 if (!fns[i + 1])
70 return fn(null);
71 // go on to next
72 run(i + 1);
73 });
74 }
75 run(0);
76 }
77 /**
78 * Targets a room when emitting.
79 *
80 * @param room
81 * @return self
82 * @public
83 */
84 to(room) {
85 return new broadcast_operator_1.BroadcastOperator(this.adapter).to(room);
86 }
87 /**
88 * Targets a room when emitting.
89 *
90 * @param room
91 * @return self
92 * @public
93 */
94 in(room) {
95 return new broadcast_operator_1.BroadcastOperator(this.adapter).in(room);
96 }
97 /**
98 * Excludes a room when emitting.
99 *
100 * @param room
101 * @return self
102 * @public
103 */
104 except(room) {
105 return new broadcast_operator_1.BroadcastOperator(this.adapter).except(room);
106 }
107 /**
108 * Adds a new client.
109 *
110 * @return {Socket}
111 * @private
112 */
113 _add(client, query, fn) {
114 debug("adding socket to nsp %s", this.name);
115 const socket = new socket_1.Socket(this, client, query);
116 this.run(socket, (err) => {
117 process.nextTick(() => {
118 if ("open" == client.conn.readyState) {
119 if (err) {
120 if (client.conn.protocol === 3) {
121 return socket._error(err.data || err.message);
122 }
123 else {
124 return socket._error({
125 message: err.message,
126 data: err.data,
127 });
128 }
129 }
130 // track socket
131 this.sockets.set(socket.id, socket);
132 // it's paramount that the internal `onconnect` logic
133 // fires before user-set events to prevent state order
134 // violations (such as a disconnection before the connection
135 // logic is complete)
136 socket._onconnect();
137 if (fn)
138 fn();
139 // fire user-set events
140 this.emitReserved("connect", socket);
141 this.emitReserved("connection", socket);
142 }
143 else {
144 debug("next called after client was closed - ignoring socket");
145 }
146 });
147 });
148 return socket;
149 }
150 /**
151 * Removes a client. Called by each `Socket`.
152 *
153 * @private
154 */
155 _remove(socket) {
156 if (this.sockets.has(socket.id)) {
157 this.sockets.delete(socket.id);
158 }
159 else {
160 debug("ignoring remove for %s", socket.id);
161 }
162 }
163 /**
164 * Emits to all clients.
165 *
166 * @return Always true
167 * @public
168 */
169 emit(ev, ...args) {
170 return new broadcast_operator_1.BroadcastOperator(this.adapter).emit(ev, ...args);
171 }
172 /**
173 * Sends a `message` event to all clients.
174 *
175 * @return self
176 * @public
177 */
178 send(...args) {
179 this.emit("message", ...args);
180 return this;
181 }
182 /**
183 * Sends a `message` event to all clients.
184 *
185 * @return self
186 * @public
187 */
188 write(...args) {
189 this.emit("message", ...args);
190 return this;
191 }
192 /**
193 * Emit a packet to other Socket.IO servers
194 *
195 * @param ev - the event name
196 * @param args - an array of arguments, which may include an acknowledgement callback at the end
197 * @public
198 */
199 serverSideEmit(ev, ...args) {
200 if (exports.RESERVED_EVENTS.has(ev)) {
201 throw new Error(`"${ev}" is a reserved event name`);
202 }
203 args.unshift(ev);
204 this.adapter.serverSideEmit(args);
205 return true;
206 }
207 /**
208 * Called when a packet is received from another Socket.IO server
209 *
210 * @param args - an array of arguments, which may include an acknowledgement callback at the end
211 *
212 * @private
213 */
214 _onServerSideEmit(args) {
215 super.emitUntyped.apply(this, args);
216 }
217 /**
218 * Gets a list of clients.
219 *
220 * @return self
221 * @public
222 */
223 allSockets() {
224 return new broadcast_operator_1.BroadcastOperator(this.adapter).allSockets();
225 }
226 /**
227 * Sets the compress flag.
228 *
229 * @param compress - if `true`, compresses the sending data
230 * @return self
231 * @public
232 */
233 compress(compress) {
234 return new broadcast_operator_1.BroadcastOperator(this.adapter).compress(compress);
235 }
236 /**
237 * Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
238 * receive messages (because of network slowness or other issues, or because they’re connected through long polling
239 * and is in the middle of a request-response cycle).
240 *
241 * @return self
242 * @public
243 */
244 get volatile() {
245 return new broadcast_operator_1.BroadcastOperator(this.adapter).volatile;
246 }
247 /**
248 * Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
249 *
250 * @return self
251 * @public
252 */
253 get local() {
254 return new broadcast_operator_1.BroadcastOperator(this.adapter).local;
255 }
256 /**
257 * Returns the matching socket instances
258 *
259 * @public
260 */
261 fetchSockets() {
262 return new broadcast_operator_1.BroadcastOperator(this.adapter).fetchSockets();
263 }
264 /**
265 * Makes the matching socket instances join the specified rooms
266 *
267 * @param room
268 * @public
269 */
270 socketsJoin(room) {
271 return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsJoin(room);
272 }
273 /**
274 * Makes the matching socket instances leave the specified rooms
275 *
276 * @param room
277 * @public
278 */
279 socketsLeave(room) {
280 return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsLeave(room);
281 }
282 /**
283 * Makes the matching socket instances disconnect
284 *
285 * @param close - whether to close the underlying connection
286 * @public
287 */
288 disconnectSockets(close = false) {
289 return new broadcast_operator_1.BroadcastOperator(this.adapter).disconnectSockets(close);
290 }
291}
292exports.Namespace = Namespace;