@subiz/wsclient 4.0.31 → 4.0.32
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/package.json +1 -1
- package/realtime.js +10 -9
- package/realtime.test.js +50 -3
package/package.json
CHANGED
package/realtime.js
CHANGED
|
@@ -17,13 +17,11 @@ var {xhrsend, parseJSON, Pubsub} = require('./common.js')
|
|
|
17
17
|
function Conn(apiUrl, credential, onDead, onEvents, callAPI, accid) {
|
|
18
18
|
callAPI = callAPI || xhrsend // allow hook
|
|
19
19
|
credential = credential || {}
|
|
20
|
-
|
|
21
20
|
var lastToken = ''
|
|
22
21
|
if (!accid) accid = ''
|
|
23
|
-
|
|
24
22
|
var is_dead = false // tell if the connection is dead
|
|
25
23
|
var is_polling_stuck = false // tell if we've having trouble doing /poll
|
|
26
|
-
var is_sub_stuck =
|
|
24
|
+
var is_sub_stuck = true // tell if we've having trouble doing /subscribe
|
|
27
25
|
|
|
28
26
|
// The long polling loop runs sequentially, with each poll starting immediately
|
|
29
27
|
// after the previous one completes. If an error occurs, the loop will pause
|
|
@@ -77,6 +75,7 @@ function Conn(apiUrl, credential, onDead, onEvents, callAPI, accid) {
|
|
|
77
75
|
// too long, kill
|
|
78
76
|
if (done) return
|
|
79
77
|
done = true
|
|
78
|
+
is_sub_stuck = true
|
|
80
79
|
resolve(repeat('dead', topics.length))
|
|
81
80
|
if (is_dead) return
|
|
82
81
|
kill('subs')
|
|
@@ -210,7 +209,7 @@ function Realtime(apiUrls, credential, callAPI, accid, skipautoreconnect) {
|
|
|
210
209
|
return conn.getStatus()
|
|
211
210
|
}
|
|
212
211
|
|
|
213
|
-
|
|
212
|
+
var subscribe = function (events) {
|
|
214
213
|
if (!conn) return Promise.resolve({error: 'dead'})
|
|
215
214
|
if (typeof events === 'string') events = [events]
|
|
216
215
|
if (!Array.isArray(events)) return Promise.resolve({error: 'param should be an array or string'})
|
|
@@ -230,11 +229,12 @@ function Realtime(apiUrls, credential, callAPI, accid, skipautoreconnect) {
|
|
|
230
229
|
return {}
|
|
231
230
|
})
|
|
232
231
|
}
|
|
232
|
+
this.subscribe = subscribe
|
|
233
233
|
|
|
234
234
|
// reconnect make sure there is alway a Conn running in the background
|
|
235
235
|
// if the Conn is dead, it recreate a new one
|
|
236
236
|
var conn
|
|
237
|
-
|
|
237
|
+
let reconnect = function () {
|
|
238
238
|
var randomUrl = apiUrls[Math.floor(Math.random() * apiUrls.length)]
|
|
239
239
|
if (conn) conn.kill() // kill old connection
|
|
240
240
|
let myconn = new Conn(
|
|
@@ -242,8 +242,9 @@ function Realtime(apiUrls, credential, callAPI, accid, skipautoreconnect) {
|
|
|
242
242
|
credential,
|
|
243
243
|
function (code, body, status) {
|
|
244
244
|
if (myconn != conn) return // outdated
|
|
245
|
+
conn = undefined // prevent dupplicate dead fire
|
|
245
246
|
pubsub.emit('interrupted', code, body, status)
|
|
246
|
-
if (!skipautoreconnect) setTimeout(
|
|
247
|
+
if (!skipautoreconnect) setTimeout(reconnect, 2000) // reconnect and resubscribe after 2 sec
|
|
247
248
|
},
|
|
248
249
|
function (events) {
|
|
249
250
|
if (myconn != conn) return
|
|
@@ -253,13 +254,13 @@ function Realtime(apiUrls, credential, callAPI, accid, skipautoreconnect) {
|
|
|
253
254
|
accid,
|
|
254
255
|
)
|
|
255
256
|
conn = myconn
|
|
256
|
-
|
|
257
257
|
var copyTopics = Object.keys(topics)
|
|
258
258
|
topics = {}
|
|
259
259
|
// resubscribe all subscribed events
|
|
260
|
-
return
|
|
260
|
+
return subscribe(copyTopics)
|
|
261
261
|
}
|
|
262
|
-
this.reconnect
|
|
262
|
+
this.reconnect = reconnect
|
|
263
|
+
reconnect()
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
// calcNextBackoff returns number of seconds we must wait
|
package/realtime.test.js
CHANGED
|
@@ -11,7 +11,7 @@ async function testScript(t, script) {
|
|
|
11
11
|
calls.push({method, url, body, cb})
|
|
12
12
|
},
|
|
13
13
|
'acctest',
|
|
14
|
-
|
|
14
|
+
!script.auto_reconnect,
|
|
15
15
|
)
|
|
16
16
|
realtime.onEvent((ev) => events.push(ev))
|
|
17
17
|
|
|
@@ -100,7 +100,6 @@ async function testScript(t, script) {
|
|
|
100
100
|
}
|
|
101
101
|
t.true(false, script.name + '[' + stepi + ']=' + step.type)
|
|
102
102
|
}
|
|
103
|
-
|
|
104
103
|
// check events
|
|
105
104
|
let scriptevents = script.events || []
|
|
106
105
|
t.equal(events.length, scriptevents.length)
|
|
@@ -278,11 +277,59 @@ test.only('realtime', async (t) => {
|
|
|
278
277
|
{type: 'status', status: 'active'},
|
|
279
278
|
],
|
|
280
279
|
},
|
|
280
|
+
{
|
|
281
|
+
name: 'reconect while poll',
|
|
282
|
+
steps: [
|
|
283
|
+
{type: 'subscribe', topics: ['message_sent']},
|
|
284
|
+
{type: 'call', call_id: 1, path: '/subs'},
|
|
285
|
+
{type: 'response', call_id: '1', body: {initial_token: 'token1'}, code: 200},
|
|
286
|
+
{type: 'call', call_id: '2', path: '/poll', query: {token: 'token1'}, method: 'get'},
|
|
287
|
+
{type: 'status', status: 'active'},
|
|
288
|
+
{type: 'wait', timeout: 1000},
|
|
289
|
+
{type: 'response', call_id: '2', body: {events: [{text: 'xin chao'}], sequential_token: 'token2'}, code: 200},
|
|
290
|
+
{type: 'call', call_id: '3', path: '/poll', query: {token: 'token2'}, method: 'get'},
|
|
291
|
+
{type: 'response', call_id: '3', body: '400 dead', code: 400},
|
|
292
|
+
{type: 'status', status: 'dead'},
|
|
293
|
+
{type: 'reconnect'},
|
|
294
|
+
{type: 'wait', timeout: 1000},
|
|
295
|
+
{type: 'call', call_id: 4, path: '/subs'},
|
|
296
|
+
{type: 'wait', timeout: 1000},
|
|
297
|
+
{type: 'response', call_id: 4, body: {initial_token: 'token1'}, code: 200},
|
|
298
|
+
{type: 'status', status: 'active'},
|
|
299
|
+
],
|
|
300
|
+
events: [{text: 'xin chao'}],
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: 'resub',
|
|
304
|
+
auto_reconnect: true,
|
|
305
|
+
steps: [
|
|
306
|
+
{type: 'subscribe', topics: ['message_sent']},
|
|
307
|
+
{type: 'call', call_id: 1, path: '/subs'},
|
|
308
|
+
{type: 'response', call_id: '1', body: 'wait a sec', code: 500},
|
|
309
|
+
{type: 'status', status: 'connecting'},
|
|
310
|
+
{type: 'wait', timeout: 1000},
|
|
311
|
+
{type: 'call', call_id: 2, path: '/subs'},
|
|
312
|
+
{type: 'wait', timeout: 61000},
|
|
313
|
+
{type: 'status', status: 'connecting'},
|
|
314
|
+
{type: 'call', call_id: 3, path: '/subs'},
|
|
315
|
+
{type: 'wait', timeout: 1000},
|
|
316
|
+
{type: 'response', call_id: '3', body: 'wait a sec', code: 500},
|
|
317
|
+
{type: 'status', status: 'connecting'},
|
|
318
|
+
{type: 'wait', timeout: 1000},
|
|
319
|
+
{type: 'call', call_id: 4, path: '/subs'},
|
|
320
|
+
{type: 'wait', timeout: 1000},
|
|
321
|
+
{type: 'response', call_id: '4', body: {initial_token: 'token1'}, code: 200},
|
|
322
|
+
{type: 'call', call_id: '5', path: '/poll', query: {token: 'token1'}, method: 'get'},
|
|
323
|
+
{type: 'status', status: 'active'},
|
|
324
|
+
{type: 'response', call_id: '5', body: {events: [{text: 'xin chao'}], sequential_token: 'token2'}, code: 200},
|
|
325
|
+
],
|
|
326
|
+
events: [{text: 'xin chao'}],
|
|
327
|
+
},
|
|
281
328
|
]
|
|
282
329
|
|
|
283
330
|
let ps = []
|
|
284
331
|
for (const script of scripts) {
|
|
285
|
-
|
|
332
|
+
if (script.name != 'resub') continue
|
|
286
333
|
ps.push(testScript(t, script))
|
|
287
334
|
}
|
|
288
335
|
await Promise.all(ps)
|