@arcblock/ws 1.16.16 → 1.17.1
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/lib/server/index.js +29 -7
- package/package.json +4 -3
package/lib/server/index.js
CHANGED
|
@@ -2,12 +2,16 @@ const EventEmitter = require('events');
|
|
|
2
2
|
const cluster = require('cluster');
|
|
3
3
|
|
|
4
4
|
const { nanoid } = require('nanoid');
|
|
5
|
+
const get = require('lodash/get');
|
|
5
6
|
const WebSocket = require('ws');
|
|
6
7
|
const eventHub = cluster.isMaster ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
|
|
7
8
|
|
|
8
9
|
const createLogger = require('../logger');
|
|
9
10
|
|
|
10
|
-
const sleep = (timeout) =>
|
|
11
|
+
const sleep = (timeout) =>
|
|
12
|
+
new Promise((resolve) => {
|
|
13
|
+
setTimeout(resolve, timeout);
|
|
14
|
+
});
|
|
11
15
|
|
|
12
16
|
const reply = (socket, topic, event, response, status = 'ok') => {
|
|
13
17
|
if (socket.readyState === WebSocket.OPEN) {
|
|
@@ -18,6 +22,7 @@ const reply = (socket, topic, event, response, status = 'ok') => {
|
|
|
18
22
|
|
|
19
23
|
const noop = () => {};
|
|
20
24
|
const defaultHooks = {
|
|
25
|
+
authenticateJoinChannel: noop,
|
|
21
26
|
preJoinChannel: noop,
|
|
22
27
|
postJoinChannel: noop,
|
|
23
28
|
preLeaveChannel: noop,
|
|
@@ -74,6 +79,7 @@ class WsServer extends EventEmitter {
|
|
|
74
79
|
const { pathname } = new URL(request.url, `http://${request.headers.host || 'unknown'}`);
|
|
75
80
|
this.logger.debug('connect attempt', { pathname });
|
|
76
81
|
if (this.pathname && pathname !== this.pathname) {
|
|
82
|
+
socket.write('HTTP/1.1 404 Pathname mismatch\r\n\r\n');
|
|
77
83
|
socket.destroy();
|
|
78
84
|
return;
|
|
79
85
|
}
|
|
@@ -128,6 +134,7 @@ class WsServer extends EventEmitter {
|
|
|
128
134
|
}
|
|
129
135
|
|
|
130
136
|
const enableLog = options.enableLog !== undefined ? !!options.enableLog : true;
|
|
137
|
+
const { socketFilters } = options;
|
|
131
138
|
const replyId = nanoid();
|
|
132
139
|
|
|
133
140
|
// Count of clients what will receive the message
|
|
@@ -139,7 +146,7 @@ class WsServer extends EventEmitter {
|
|
|
139
146
|
}
|
|
140
147
|
});
|
|
141
148
|
|
|
142
|
-
eventHub.broadcast(this.broadcastEventName, { topic, event, data, options, enableLog, replyId });
|
|
149
|
+
eventHub.broadcast(this.broadcastEventName, { topic, event, data, options, enableLog, replyId, socketFilters });
|
|
143
150
|
|
|
144
151
|
// wait 600ms for message sending by each process
|
|
145
152
|
await sleep(600);
|
|
@@ -154,11 +161,16 @@ class WsServer extends EventEmitter {
|
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
|
|
157
|
-
async _doBroadCast({ topic, event, data, enableLog, replyId } = {}) {
|
|
164
|
+
async _doBroadCast({ topic, event, data, enableLog, replyId, socketFilters } = {}) {
|
|
158
165
|
try {
|
|
159
166
|
let count = 0;
|
|
160
167
|
|
|
161
168
|
if (this.topics[topic] && this.topics[topic].size) {
|
|
169
|
+
let conditions = null;
|
|
170
|
+
if (socketFilters && Object.keys(socketFilters).length) {
|
|
171
|
+
conditions = Object.entries(socketFilters);
|
|
172
|
+
}
|
|
173
|
+
|
|
162
174
|
this.topics[topic].forEach((socket) => {
|
|
163
175
|
const noHeartbeatTime = Date.now() - socket.heartbeatAt;
|
|
164
176
|
if (noHeartbeatTime > this.heartbeatTimeout) {
|
|
@@ -170,6 +182,10 @@ class WsServer extends EventEmitter {
|
|
|
170
182
|
return;
|
|
171
183
|
}
|
|
172
184
|
|
|
185
|
+
if (conditions && !conditions.every(([key, value]) => get(socket, key) === value)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
173
189
|
count++;
|
|
174
190
|
if (enableLog) {
|
|
175
191
|
this.logger.info('broadcast message to', { topic, event, id: socket.id });
|
|
@@ -240,6 +256,8 @@ class WsServer extends EventEmitter {
|
|
|
240
256
|
*/
|
|
241
257
|
async onWssConnection(socket) {
|
|
242
258
|
socket.id = nanoid();
|
|
259
|
+
socket.channel = {};
|
|
260
|
+
|
|
243
261
|
refreshHeartbeat(socket);
|
|
244
262
|
this.logger.debug('socket connected', { id: socket.id });
|
|
245
263
|
|
|
@@ -275,7 +293,11 @@ class WsServer extends EventEmitter {
|
|
|
275
293
|
if (event === 'phx_join') {
|
|
276
294
|
// pre hook
|
|
277
295
|
try {
|
|
278
|
-
await this.hooks.
|
|
296
|
+
const authInfo = await this.hooks.authenticateJoinChannel({ socket, joinRef, ref, topic, event, payload });
|
|
297
|
+
await this.hooks.preJoinChannel({ socket, joinRef, ref, topic, event, payload });
|
|
298
|
+
|
|
299
|
+
socket.channel[topic] = {};
|
|
300
|
+
socket.channel[topic].authInfo = authInfo;
|
|
279
301
|
} catch (error) {
|
|
280
302
|
this.logger.error('preJoinChannel error', { error });
|
|
281
303
|
reply(socket, topic, `chan_reply_${ref}`, { message: error.message }, 'error');
|
|
@@ -293,7 +315,7 @@ class WsServer extends EventEmitter {
|
|
|
293
315
|
|
|
294
316
|
// post hook
|
|
295
317
|
try {
|
|
296
|
-
await this.hooks.postJoinChannel({ joinRef, ref, topic, event, payload });
|
|
318
|
+
await this.hooks.postJoinChannel({ socket, joinRef, ref, topic, event, payload });
|
|
297
319
|
} catch (error) {
|
|
298
320
|
this.logger.error('postJoinChannel error', { error });
|
|
299
321
|
}
|
|
@@ -304,7 +326,7 @@ class WsServer extends EventEmitter {
|
|
|
304
326
|
if (event === 'phx_leave') {
|
|
305
327
|
// pre hook
|
|
306
328
|
try {
|
|
307
|
-
await this.hooks.preLeaveChannel({ joinRef, ref, topic, event, payload });
|
|
329
|
+
await this.hooks.preLeaveChannel({ socket, joinRef, ref, topic, event, payload });
|
|
308
330
|
} catch (error) {
|
|
309
331
|
this.logger.error('preLeaveChannel error', { error });
|
|
310
332
|
reply(socket, topic, `chan_reply_${ref}`, { message: error.message }, 'error');
|
|
@@ -317,7 +339,7 @@ class WsServer extends EventEmitter {
|
|
|
317
339
|
|
|
318
340
|
// post hook
|
|
319
341
|
try {
|
|
320
|
-
await this.hooks.postLeaveChannel({ joinRef, ref, topic, event, payload });
|
|
342
|
+
await this.hooks.postLeaveChannel({ socket, joinRef, ref, topic, event, payload });
|
|
321
343
|
} catch (error) {
|
|
322
344
|
this.logger.error('postLeaveChannel error', { error });
|
|
323
345
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ws",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.1",
|
|
4
4
|
"description": "OCAP Chain websocket server and client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"websocket"
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"url": "https://github.com/ArcBlock/asset-chain/issues"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@arcblock/event-hub": "1.
|
|
37
|
+
"@arcblock/event-hub": "1.17.1",
|
|
38
38
|
"debug": "^4.3.3",
|
|
39
39
|
"eventemitter3": "^4.0.4",
|
|
40
|
+
"lodash": "^4.17.21",
|
|
40
41
|
"nanoid": "3.x",
|
|
41
42
|
"phoenix": "1.5.12",
|
|
42
43
|
"ws": "^8.2.2"
|
|
@@ -44,5 +45,5 @@
|
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"get-port": "^5.1.1"
|
|
46
47
|
},
|
|
47
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "ca2ac264d9d6358680d5be99fcdd4685d0c999fc"
|
|
48
49
|
}
|