@arcblock/ws 1.17.0 → 1.17.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,7 @@ 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
 
@@ -21,6 +22,7 @@ const reply = (socket, topic, event, response, status = 'ok') => {
21
22
 
22
23
  const noop = () => {};
23
24
  const defaultHooks = {
25
+ authenticateJoinChannel: noop,
24
26
  preJoinChannel: noop,
25
27
  postJoinChannel: noop,
26
28
  preLeaveChannel: noop,
@@ -132,6 +134,7 @@ class WsServer extends EventEmitter {
132
134
  }
133
135
 
134
136
  const enableLog = options.enableLog !== undefined ? !!options.enableLog : true;
137
+ const { socketFilters } = options;
135
138
  const replyId = nanoid();
136
139
 
137
140
  // Count of clients what will receive the message
@@ -143,7 +146,7 @@ class WsServer extends EventEmitter {
143
146
  }
144
147
  });
145
148
 
146
- eventHub.broadcast(this.broadcastEventName, { topic, event, data, options, enableLog, replyId });
149
+ eventHub.broadcast(this.broadcastEventName, { topic, event, data, options, enableLog, replyId, socketFilters });
147
150
 
148
151
  // wait 600ms for message sending by each process
149
152
  await sleep(600);
@@ -158,11 +161,16 @@ class WsServer extends EventEmitter {
158
161
  }
159
162
  }
160
163
 
161
- async _doBroadCast({ topic, event, data, enableLog, replyId } = {}) {
164
+ async _doBroadCast({ topic, event, data, enableLog, replyId, socketFilters } = {}) {
162
165
  try {
163
166
  let count = 0;
164
167
 
165
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
+
166
174
  this.topics[topic].forEach((socket) => {
167
175
  const noHeartbeatTime = Date.now() - socket.heartbeatAt;
168
176
  if (noHeartbeatTime > this.heartbeatTimeout) {
@@ -174,6 +182,10 @@ class WsServer extends EventEmitter {
174
182
  return;
175
183
  }
176
184
 
185
+ if (conditions && !conditions.every(([key, value]) => get(socket, key) === value)) {
186
+ return;
187
+ }
188
+
177
189
  count++;
178
190
  if (enableLog) {
179
191
  this.logger.info('broadcast message to', { topic, event, id: socket.id });
@@ -244,6 +256,8 @@ class WsServer extends EventEmitter {
244
256
  */
245
257
  async onWssConnection(socket) {
246
258
  socket.id = nanoid();
259
+ socket.channel = {};
260
+
247
261
  refreshHeartbeat(socket);
248
262
  this.logger.debug('socket connected', { id: socket.id });
249
263
 
@@ -279,7 +293,11 @@ class WsServer extends EventEmitter {
279
293
  if (event === 'phx_join') {
280
294
  // pre hook
281
295
  try {
282
- await this.hooks.preJoinChannel({ joinRef, ref, topic, event, payload });
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;
283
301
  } catch (error) {
284
302
  this.logger.error('preJoinChannel error', { error });
285
303
  reply(socket, topic, `chan_reply_${ref}`, { message: error.message }, 'error');
@@ -297,7 +315,7 @@ class WsServer extends EventEmitter {
297
315
 
298
316
  // post hook
299
317
  try {
300
- await this.hooks.postJoinChannel({ joinRef, ref, topic, event, payload });
318
+ await this.hooks.postJoinChannel({ socket, joinRef, ref, topic, event, payload });
301
319
  } catch (error) {
302
320
  this.logger.error('postJoinChannel error', { error });
303
321
  }
@@ -308,7 +326,7 @@ class WsServer extends EventEmitter {
308
326
  if (event === 'phx_leave') {
309
327
  // pre hook
310
328
  try {
311
- await this.hooks.preLeaveChannel({ joinRef, ref, topic, event, payload });
329
+ await this.hooks.preLeaveChannel({ socket, joinRef, ref, topic, event, payload });
312
330
  } catch (error) {
313
331
  this.logger.error('preLeaveChannel error', { error });
314
332
  reply(socket, topic, `chan_reply_${ref}`, { message: error.message }, 'error');
@@ -321,7 +339,7 @@ class WsServer extends EventEmitter {
321
339
 
322
340
  // post hook
323
341
  try {
324
- await this.hooks.postLeaveChannel({ joinRef, ref, topic, event, payload });
342
+ await this.hooks.postLeaveChannel({ socket, joinRef, ref, topic, event, payload });
325
343
  } catch (error) {
326
344
  this.logger.error('postLeaveChannel error', { error });
327
345
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ws",
3
- "version": "1.17.0",
3
+ "version": "1.17.3",
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.17.0",
37
+ "@arcblock/event-hub": "1.17.3",
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": "f0944b60a5fb4115e1a3727bb07f68174bc56c5c"
48
+ "gitHead": "7a74e4e2b362a6e6ea8d14617f0480966c3363d5"
48
49
  }