@arcblock/ws 1.16.16 → 1.17.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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) => new Promise((resolve) => setTimeout(resolve, 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.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;
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.16.16",
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.16.16",
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": "051f9620995cf24407374cc4811b0fa6ed6dc7ca"
48
+ "gitHead": "ca2ac264d9d6358680d5be99fcdd4685d0c999fc"
48
49
  }