@soundworks/core 4.0.0-alpha.0 → 4.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -16
- package/package.json +2 -2
- package/src/client/Client.js +37 -3
- package/src/client/Context.js +37 -10
- package/src/client/Plugin.js +2 -1
- package/src/client/PluginManager.js +26 -17
- package/src/client/Socket.js +44 -39
- package/src/client/index.js +0 -33
- package/src/common/BasePluginManager.js +12 -3
- package/src/common/ParameterBag.js +7 -196
- package/src/server/Context.js +162 -18
- package/src/server/ContextManager.js +4 -5
- package/src/server/Plugin.js +2 -1
- package/src/server/PluginManager.js +26 -6
- package/src/server/Server.js +185 -69
- package/src/server/Socket.js +105 -62
- package/src/server/Sockets.js +27 -22
- package/src/server/StateManager.js +223 -24
- package/src/server/index.js +0 -20
package/src/server/Socket.js
CHANGED
|
@@ -6,66 +6,80 @@ import {
|
|
|
6
6
|
unpackStringMessage,
|
|
7
7
|
} from '../common/sockets-utils.js';
|
|
8
8
|
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
9
|
+
// Status codes:
|
|
10
|
+
//
|
|
11
|
+
// CONNECTING = 0;
|
|
12
|
+
// OPEN = 1;
|
|
13
|
+
// CLOSING = 2;
|
|
14
|
+
// CLOSED = 3;
|
|
15
|
+
// READY_STATES = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* - one configured with `binaryType=arraybuffer` for streaming data more
|
|
20
|
-
* efficiently.
|
|
18
|
+
* The Socket class is a simple publish / subscribe wrapper built on top of the
|
|
19
|
+
* [ws](https://github.com/websockets/ws) library. An instance of {@link server.Socket}
|
|
20
|
+
* is automatically created per client when it connects (see {@link server.Client#socket}).
|
|
21
21
|
*
|
|
22
|
-
* @
|
|
22
|
+
* _Important: In most cases, you should consider using a {@link client.SharedState}
|
|
23
|
+
* rather than directly using the sockets._
|
|
24
|
+
*
|
|
25
|
+
* The Socket class contains two different WebSockets:
|
|
26
|
+
* - a socket configured with `binaryType = 'blob'` for JSON compatible data
|
|
27
|
+
* types (i.e. string, number, boolean, object, array and null).
|
|
28
|
+
* - a socket configured with `binaryType= 'arraybuffer'` for efficient streaming
|
|
29
|
+
* of binary data.
|
|
23
30
|
*
|
|
24
31
|
* @memberof server
|
|
32
|
+
* @hideconstructor
|
|
25
33
|
*/
|
|
26
34
|
class Socket {
|
|
27
35
|
constructor(ws, binaryWs, rooms, sockets, options = {}) {
|
|
28
|
-
|
|
29
36
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @type {
|
|
33
|
-
* @example
|
|
34
|
-
* socket.sockets.broadcast('my-room', this, 'update-value', 1);
|
|
37
|
+
* Configuration object
|
|
38
|
+
*
|
|
39
|
+
* @type {object}
|
|
35
40
|
*/
|
|
36
|
-
this.
|
|
41
|
+
this.config = {
|
|
42
|
+
pingInterval: 5 * 1000,
|
|
43
|
+
...options,
|
|
44
|
+
};
|
|
37
45
|
|
|
38
46
|
/**
|
|
39
47
|
* `ws` socket instance configured with `binaryType=blob` (string)
|
|
48
|
+
*
|
|
49
|
+
* @type {object}
|
|
40
50
|
* @private
|
|
41
|
-
* @type {Object}
|
|
42
51
|
*/
|
|
43
52
|
this.ws = ws;
|
|
44
53
|
|
|
45
54
|
/**
|
|
46
55
|
* `ws` socket instance configured with `binaryType=arraybuffer` (TypedArray)
|
|
56
|
+
*
|
|
57
|
+
* @type {object}
|
|
47
58
|
* @private
|
|
48
|
-
* @type {Object}
|
|
49
59
|
*/
|
|
50
60
|
this.binaryWs = binaryWs;
|
|
51
61
|
|
|
52
62
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
63
|
+
* Reference to the sockets object, is mainly dedicated to allow
|
|
64
|
+
* broadcasting from a given socket instance.
|
|
65
|
+
*
|
|
66
|
+
* @type {server.Sockets}
|
|
67
|
+
* @example
|
|
68
|
+
* socket.sockets.broadcast('my-room', this, 'update-value', 1);
|
|
56
69
|
*/
|
|
57
|
-
this.
|
|
70
|
+
this.sockets = sockets;
|
|
58
71
|
|
|
59
72
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
73
|
+
* Reference to the rooms object
|
|
74
|
+
*
|
|
75
|
+
* @type {Map}
|
|
76
|
+
* @private
|
|
62
77
|
*/
|
|
63
|
-
this.
|
|
64
|
-
pingInterval: 5 * 1000,
|
|
65
|
-
...options,
|
|
66
|
-
};
|
|
78
|
+
this.rooms = rooms;
|
|
67
79
|
|
|
80
|
+
/** @private */
|
|
68
81
|
this._stringListeners = new Map();
|
|
82
|
+
/** @private */
|
|
69
83
|
this._binaryListeners = new Map();
|
|
70
84
|
|
|
71
85
|
// ----------------------------------------------------------
|
|
@@ -150,9 +164,11 @@ class Socket {
|
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
/**
|
|
153
|
-
*
|
|
167
|
+
* Removes all listeners and immediately close the two sockets. Is automatically
|
|
168
|
+
* called on `server.stop()`
|
|
169
|
+
*
|
|
170
|
+
* @private
|
|
154
171
|
*/
|
|
155
|
-
/** @private */
|
|
156
172
|
terminate() {
|
|
157
173
|
// clear ping/pong check
|
|
158
174
|
clearInterval(this._intervalId);
|
|
@@ -190,7 +206,12 @@ class Socket {
|
|
|
190
206
|
this.ws.terminate();
|
|
191
207
|
}
|
|
192
208
|
|
|
193
|
-
/**
|
|
209
|
+
/**
|
|
210
|
+
* @param {boolean} binary - Emit to either the string or binary socket.
|
|
211
|
+
* @param {string} channel - Channel name.
|
|
212
|
+
* @param {...*} args - Content of the message.
|
|
213
|
+
* @private
|
|
214
|
+
*/
|
|
194
215
|
_emit(binary, channel, ...args) {
|
|
195
216
|
const listeners = binary ? this._binaryListeners : this._stringListeners;
|
|
196
217
|
|
|
@@ -200,7 +221,12 @@ class Socket {
|
|
|
200
221
|
}
|
|
201
222
|
}
|
|
202
223
|
|
|
203
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* @param {Function[]} listeners - List of listeners, either for the string or binary socket.
|
|
226
|
+
* @param {string} channel - Channel name.
|
|
227
|
+
* @param {Function} callback - The function to be added to the listeners.
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
204
230
|
_addListener(listeners, channel, callback) {
|
|
205
231
|
if (!listeners.has(channel)) {
|
|
206
232
|
listeners.set(channel, new Set());
|
|
@@ -210,7 +236,12 @@ class Socket {
|
|
|
210
236
|
callbacks.add(callback);
|
|
211
237
|
}
|
|
212
238
|
|
|
213
|
-
/**
|
|
239
|
+
/**
|
|
240
|
+
* @param {Function[]} listeners - List of listeners, either for the string or binary socket.
|
|
241
|
+
* @param {string} channel - Channel name.
|
|
242
|
+
* @param {Function} callback - The function to be removed from the listeners.
|
|
243
|
+
* @private
|
|
244
|
+
*/
|
|
214
245
|
_removeListener(listeners, channel, callback) {
|
|
215
246
|
if (listeners.has(channel)) {
|
|
216
247
|
const callbacks = listeners.get(channel);
|
|
@@ -222,16 +253,24 @@ class Socket {
|
|
|
222
253
|
}
|
|
223
254
|
}
|
|
224
255
|
|
|
225
|
-
/**
|
|
256
|
+
/**
|
|
257
|
+
* @param {Function[]} listeners - List of listeners, either for the string or binary socket.
|
|
258
|
+
* @param {string} [channel=null] - Channel name of the listeners to remove. If null
|
|
259
|
+
* all the listeners are cleared.
|
|
260
|
+
* @private
|
|
261
|
+
*/
|
|
226
262
|
_removeAllListeners(listeners, channel) {
|
|
227
|
-
if (
|
|
263
|
+
if (channel === null) {
|
|
264
|
+
listeners.clear();
|
|
265
|
+
} else if (listeners.has(channel)) {
|
|
228
266
|
listeners.delete(channel);
|
|
229
267
|
}
|
|
230
268
|
}
|
|
231
269
|
|
|
232
270
|
/**
|
|
233
271
|
* Add the socket to a room
|
|
234
|
-
*
|
|
272
|
+
*
|
|
273
|
+
* @param {string} roomId - Id of the room.
|
|
235
274
|
*/
|
|
236
275
|
addToRoom(roomId) {
|
|
237
276
|
if (!this.rooms.has(roomId)) {
|
|
@@ -244,7 +283,8 @@ class Socket {
|
|
|
244
283
|
|
|
245
284
|
/**
|
|
246
285
|
* Remove the socket from a room
|
|
247
|
-
*
|
|
286
|
+
*
|
|
287
|
+
* @param {string} roomId - Id of the room.
|
|
248
288
|
*/
|
|
249
289
|
removeFromRoom(roomId) {
|
|
250
290
|
if (this.rooms.has(roomId)) {
|
|
@@ -254,10 +294,11 @@ class Socket {
|
|
|
254
294
|
}
|
|
255
295
|
|
|
256
296
|
/**
|
|
257
|
-
*
|
|
297
|
+
* Send messages with JSON compatible data types on a given channel.
|
|
258
298
|
*
|
|
259
|
-
* @param {
|
|
260
|
-
* @param {...*} args -
|
|
299
|
+
* @param {string} channel - Channel name.
|
|
300
|
+
* @param {...*} args - Payload of the message. As many arguments as needed, of
|
|
301
|
+
* JSON compatible data types (i.e. string, number, boolean, object, array and null).
|
|
261
302
|
*/
|
|
262
303
|
send(channel, ...args) {
|
|
263
304
|
const msg = packStringMessage(channel, ...args);
|
|
@@ -276,39 +317,41 @@ class Socket {
|
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
/**
|
|
279
|
-
* Listen JSON compatible
|
|
320
|
+
* Listen messages with JSON compatible data types on a given channel.
|
|
280
321
|
*
|
|
281
|
-
* @param {
|
|
282
|
-
* @param {Function} callback - Callback to execute when a message is received
|
|
322
|
+
* @param {string} channel - Channel name.
|
|
323
|
+
* @param {Function} callback - Callback to execute when a message is received,
|
|
324
|
+
* arguments of the callback function will match the arguments sent using the
|
|
325
|
+
* {@link server.Socket#send} method.
|
|
283
326
|
*/
|
|
284
327
|
addListener(channel, callback) {
|
|
285
328
|
this._addListener(this._stringListeners, channel, callback);
|
|
286
329
|
}
|
|
287
330
|
|
|
288
331
|
/**
|
|
289
|
-
* Remove a listener
|
|
332
|
+
* Remove a listener of messages with JSON compatible data types from a given channel.
|
|
290
333
|
*
|
|
291
|
-
* @param {
|
|
292
|
-
* @param {Function} callback - Callback to
|
|
334
|
+
* @param {string} channel - Channel name.
|
|
335
|
+
* @param {Function} callback - Callback to remove.
|
|
293
336
|
*/
|
|
294
337
|
removeListener(channel, callback) {
|
|
295
338
|
this._removeListener(this._stringListeners, channel, callback);
|
|
296
339
|
}
|
|
297
340
|
|
|
298
341
|
/**
|
|
299
|
-
* Remove all listeners
|
|
342
|
+
* Remove all listeners of messages with JSON compatible data types.
|
|
300
343
|
*
|
|
301
|
-
* @param {
|
|
344
|
+
* @param {string} channel - Channel name.
|
|
302
345
|
*/
|
|
303
|
-
removeAllListeners(channel) {
|
|
346
|
+
removeAllListeners(channel = null) {
|
|
304
347
|
this._removeAllListeners(this._stringListeners, channel);
|
|
305
348
|
}
|
|
306
349
|
|
|
307
350
|
/**
|
|
308
|
-
*
|
|
351
|
+
* Send binary messages on a given channel.
|
|
309
352
|
*
|
|
310
|
-
* @param {
|
|
311
|
-
* @param {TypedArray} typedArray -
|
|
353
|
+
* @param {string} channel - Channel name.
|
|
354
|
+
* @param {TypedArray} typedArray - Binary data to be sent.
|
|
312
355
|
*/
|
|
313
356
|
sendBinary(channel, typedArray) {
|
|
314
357
|
const msg = packBinaryMessage(channel, typedArray);
|
|
@@ -323,29 +366,29 @@ class Socket {
|
|
|
323
366
|
/**
|
|
324
367
|
* Listen binary messages on a given channel
|
|
325
368
|
*
|
|
326
|
-
* @param {
|
|
327
|
-
* @param {Function} callback - Callback to execute when a message is received
|
|
369
|
+
* @param {string} channel - Channel name.
|
|
370
|
+
* @param {Function} callback - Callback to execute when a message is received.
|
|
328
371
|
*/
|
|
329
372
|
addBinaryListener(channel, callback) {
|
|
330
373
|
this._addListener(this._binaryListeners, channel, callback);
|
|
331
374
|
}
|
|
332
375
|
|
|
333
376
|
/**
|
|
334
|
-
* Remove a listener
|
|
377
|
+
* Remove a listener of binary compatible messages from a given channel
|
|
335
378
|
*
|
|
336
|
-
* @param {
|
|
337
|
-
* @param {Function} callback - Callback to
|
|
379
|
+
* @param {string} channel - Channel name.
|
|
380
|
+
* @param {Function} callback - Callback to remove.
|
|
338
381
|
*/
|
|
339
382
|
removeBinaryListener(channel, callback) {
|
|
340
383
|
this._removeListener(this._binaryListeners, channel, callback);
|
|
341
384
|
}
|
|
342
385
|
|
|
343
386
|
/**
|
|
344
|
-
* Remove all listeners
|
|
387
|
+
* Remove all listeners of binary compatible messages on a given channel
|
|
345
388
|
*
|
|
346
|
-
* @param {
|
|
389
|
+
* @param {string} channel - Channel of the message.
|
|
347
390
|
*/
|
|
348
|
-
removeAllBinaryListeners(channel) {
|
|
391
|
+
removeAllBinaryListeners(channel = null) {
|
|
349
392
|
this._removeAllListeners(this._binaryListeners, channel);
|
|
350
393
|
}
|
|
351
394
|
}
|
package/src/server/Sockets.js
CHANGED
|
@@ -11,7 +11,8 @@ import Socket from './Socket.js';
|
|
|
11
11
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Manager all {@link server.Socket} instances.
|
|
15
|
+
*
|
|
15
16
|
* Most of the time, you shouldn't have to use this class instance directely, but
|
|
16
17
|
* it could be usefull in some situations, for broadcasting messages, creating rooms, etc.
|
|
17
18
|
*
|
|
@@ -36,9 +37,9 @@ class Sockets {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
* Initialize sockets, all sockets are added
|
|
40
|
+
* Initialize sockets, all sockets are added to two rooms by default:
|
|
40
41
|
* - to the room corresponding to the client `role`
|
|
41
|
-
* - to the '*' that holds all connected sockets
|
|
42
|
+
* - to the '*' room that holds all connected sockets
|
|
42
43
|
*
|
|
43
44
|
* @private
|
|
44
45
|
*/
|
|
@@ -100,7 +101,11 @@ class Sockets {
|
|
|
100
101
|
});
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Terminate all existing sockets
|
|
106
|
+
*
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
104
109
|
terminate() {
|
|
105
110
|
// terminate stat worker thread
|
|
106
111
|
this._latencyStatsWorker.terminate();
|
|
@@ -146,7 +151,7 @@ class Sockets {
|
|
|
146
151
|
* Add a socket to a room
|
|
147
152
|
*
|
|
148
153
|
* @param {server.Socket} socket - Socket to add to the room.
|
|
149
|
-
* @param {String} roomId - Id of the room
|
|
154
|
+
* @param {String} roomId - Id of the room.
|
|
150
155
|
*/
|
|
151
156
|
addToRoom(socket, roomId) {
|
|
152
157
|
socket.addToRoom(roomId);
|
|
@@ -156,39 +161,39 @@ class Sockets {
|
|
|
156
161
|
* Remove a socket from a room
|
|
157
162
|
*
|
|
158
163
|
* @param {server.Socket} socket - Socket to remove from the room.
|
|
159
|
-
* @param {String}
|
|
164
|
+
* @param {String} roomId - Id of the room.
|
|
160
165
|
*/
|
|
161
166
|
removeFromRoom(socket, roomId) {
|
|
162
167
|
socket.removeFromRoom(roomId);
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
/**
|
|
166
|
-
* Send a
|
|
167
|
-
*
|
|
171
|
+
* Send a message of JSON compatible data types to all client of given room(s).
|
|
172
|
+
* If no room is specified, the message is sent to all clients.
|
|
173
|
+
*
|
|
168
174
|
*
|
|
169
175
|
* @param {String|Array} roomsIds - Ids of the rooms that must receive
|
|
170
|
-
* the message. If null the message is sent to all clients
|
|
171
|
-
* @param {server.Socket} excludeSocket - Optionnal
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* @param {
|
|
175
|
-
*
|
|
176
|
+
* the message. If `null` the message is sent to all clients.
|
|
177
|
+
* @param {server.Socket} excludeSocket - Optionnal socket to ignore when
|
|
178
|
+
* broadcasting the message, typically the client at the origin of the message.
|
|
179
|
+
* @param {String} channel - Channel name.
|
|
180
|
+
* @param {...*} args - Payload of the message. As many arguments as needed, of
|
|
181
|
+
* JSON compatible data types (i.e. string, number, boolean, object, array and null).
|
|
176
182
|
*/
|
|
177
183
|
broadcast(roomIds, excludeSocket, channel, ...args) {
|
|
178
184
|
this._broadcast(false, roomIds, excludeSocket, channel, ...args);
|
|
179
185
|
}
|
|
180
186
|
|
|
181
187
|
/**
|
|
182
|
-
* Send a binary message
|
|
183
|
-
*
|
|
188
|
+
* Send a binary message to all client of given room(s). If no room is specified
|
|
189
|
+
* specified, the message is sent to all clients.
|
|
184
190
|
*
|
|
185
191
|
* @param {String|Array} roomsIds - Ids of the rooms that must receive
|
|
186
|
-
* the message. If null the message is sent to all clients
|
|
187
|
-
* @param {server.Socket} excludeSocket - Optionnal
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
* @param {
|
|
191
|
-
* @param {...*} args - Arguments of the message (as many as needed, of any type)
|
|
192
|
+
* the message. If `null` the message is sent to all clients.
|
|
193
|
+
* @param {server.Socket} excludeSocket - Optionnal socket to ignore when
|
|
194
|
+
* broadcasting the message, typically the client at the origin of the message.
|
|
195
|
+
* @param {string} channel - Channel name.
|
|
196
|
+
* @param {TypedArray} typedArray - Binary data to be sent.
|
|
192
197
|
*/
|
|
193
198
|
broadcastBinary(roomIds, excludeSocket, channel, typedArray) {
|
|
194
199
|
this._broadcast(true, roomIds, excludeSocket, channel, typedArray);
|