quickblox 2.24.1-alpha.0 → 2.24.1-alpha.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/package.json +1 -1
- package/quickblox.js +110 -13
- package/quickblox.min.js +1 -1
- package/src/modules/chat/qbChat.js +109 -12
- package/src/qbConfig.js +1 -1
|
@@ -11,6 +11,13 @@ var chatUtils = require('./qbChatHelpers'),
|
|
|
11
11
|
|
|
12
12
|
var unsupportedError = 'This function isn\'t supported outside of the browser (...yet)';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* [CROS-1061] How long to wait for the server to answer a Notice enable/disable
|
|
16
|
+
* IQ before reporting an error to the caller. Without a bound the callback is
|
|
17
|
+
* never invoked when the server stays silent.
|
|
18
|
+
*/
|
|
19
|
+
var NOTICE_IQ_TIMEOUT_MS = 10000;
|
|
20
|
+
|
|
14
21
|
var XMPP;
|
|
15
22
|
|
|
16
23
|
/** create StropheJS or NodeXMPP connection object */
|
|
@@ -1852,6 +1859,22 @@ ChatProxy.prototype = {
|
|
|
1852
1859
|
self._isConnecting = false;
|
|
1853
1860
|
self._sessionHasExpired = false;
|
|
1854
1861
|
|
|
1862
|
+
// [CROS-1061] A new XMPP session never carries the previous session's
|
|
1863
|
+
// Notice subscription: the server binds <enable xmlns="urn:xmpp:notice:0"/>
|
|
1864
|
+
// to the stream, so it is gone once the stream is gone. Without this
|
|
1865
|
+
// reset the flag stays `true` after a transport reconnect while no
|
|
1866
|
+
// notices are delivered any more, and isNoticesEnabled() misleads the
|
|
1867
|
+
// application into skipping the re-enable (verified against a live
|
|
1868
|
+
// server: socket break -> reconnect -> flag true, zero notice stanzas;
|
|
1869
|
+
// clearing the flag and re-sending <enable> restored delivery).
|
|
1870
|
+
//
|
|
1871
|
+
// Placed in the shared preamble, above the isInitialConnect branch, and
|
|
1872
|
+
// above the onReconnectListener call below: with
|
|
1873
|
+
// config.pingLocalhostTimeInterval === 0 that listener fires
|
|
1874
|
+
// synchronously from this function, and a consumer re-enabling notices
|
|
1875
|
+
// from it must not observe a stale `true`.
|
|
1876
|
+
self._isNoticesEnabled = false;
|
|
1877
|
+
|
|
1855
1878
|
self._enableCarbons();
|
|
1856
1879
|
|
|
1857
1880
|
if (isInitialConnect) {
|
|
@@ -1862,7 +1885,6 @@ ChatProxy.prototype = {
|
|
|
1862
1885
|
self._isConnectionVerified = true;
|
|
1863
1886
|
self._isReconnectListenerPending = false;
|
|
1864
1887
|
|
|
1865
|
-
// TODO(2.25.0): auto-enable Notice Feature here (see qbChat.js enableNotices JSDoc).
|
|
1866
1888
|
self.roster.get(function (contacts) {
|
|
1867
1889
|
xmppClient.send(presence);
|
|
1868
1890
|
|
|
@@ -1870,7 +1892,24 @@ ChatProxy.prototype = {
|
|
|
1870
1892
|
callback(self.roster.contacts);
|
|
1871
1893
|
});
|
|
1872
1894
|
} else {
|
|
1895
|
+
// [CROS-1061] Union of the rooms still tracked on this instance and
|
|
1896
|
+
// the ones an explicit reconnect() had to drop. Consumed once —
|
|
1897
|
+
// clearing it here keeps a later session (or another user after
|
|
1898
|
+
// logout) from resurrecting a stale list.
|
|
1899
|
+
//
|
|
1900
|
+
// Safe to build the join stanzas at this point: setUserCurrentJid()
|
|
1901
|
+
// above has already installed the new JID, and muc.join() derives
|
|
1902
|
+
// the presence `from` out of it. Moving this block above that call
|
|
1903
|
+
// would send from="".
|
|
1873
1904
|
var rooms = Object.keys(self.muc.joinedRooms);
|
|
1905
|
+
var remembered = self.muc._roomsToRejoin || [];
|
|
1906
|
+
|
|
1907
|
+
for (var r = 0; r < remembered.length; r++) {
|
|
1908
|
+
if (rooms.indexOf(remembered[r]) === -1) {
|
|
1909
|
+
rooms.push(remembered[r]);
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
self.muc._roomsToRejoin = [];
|
|
1874
1913
|
|
|
1875
1914
|
xmppClient.send(presence);
|
|
1876
1915
|
|
|
@@ -2093,6 +2132,11 @@ ChatProxy.prototype = {
|
|
|
2093
2132
|
// connection had a chance to verify itself.
|
|
2094
2133
|
this._isConnectionVerified = false;
|
|
2095
2134
|
this._isReconnectListenerPending = false;
|
|
2135
|
+
// [CROS-1061] Remember the rooms before dropping them, so the re-join
|
|
2136
|
+
// loop in _postConnectActions has something to restore. Without this the
|
|
2137
|
+
// list is lost and group dialogs stop receiving message-level notices
|
|
2138
|
+
// until the page is reloaded.
|
|
2139
|
+
this.muc._roomsToRejoin = Object.keys(this.muc.joinedRooms);
|
|
2096
2140
|
this.muc.joinedRooms = {};
|
|
2097
2141
|
this.helpers.setUserCurrentJid('');
|
|
2098
2142
|
|
|
@@ -2486,6 +2530,9 @@ ChatProxy.prototype = {
|
|
|
2486
2530
|
this._checkConnectionTimer = undefined;
|
|
2487
2531
|
this._checkExpiredSessionTimer = undefined;
|
|
2488
2532
|
this.muc.joinedRooms = {};
|
|
2533
|
+
// [CROS-1061] Never carry rooms across a logout: re-joining the previous
|
|
2534
|
+
// user's rooms from a new JID is answered with 403/407 by the server.
|
|
2535
|
+
this.muc._roomsToRejoin = [];
|
|
2489
2536
|
// [QC-1550] Reset XMPP verification state on explicit disconnect so the
|
|
2490
2537
|
// next connect() starts from a clean slate. _isLogout guard below also
|
|
2491
2538
|
// prevents firing of deferred listeners if a pong arrives in flight,
|
|
@@ -2520,17 +2567,26 @@ ChatProxy.prototype = {
|
|
|
2520
2567
|
* NoticeCreatedDialog / NoticeUpdatedDialog / NoticeDeletedDialog
|
|
2521
2568
|
* headline stanzas.
|
|
2522
2569
|
*
|
|
2523
|
-
* The
|
|
2524
|
-
*
|
|
2525
|
-
*
|
|
2570
|
+
* The subscription belongs to the XMPP session, so it does not survive a
|
|
2571
|
+
* reconnect: the local enabled flag is reset to false whenever a new session
|
|
2572
|
+
* is established (initial connect and every reconnect alike) as well as on
|
|
2573
|
+
* disconnect. Consumers must call enableNotices() again after a reconnect —
|
|
2574
|
+
* an intentional divergence from the Android SDK, which auto-restores the
|
|
2575
|
+
* subscription. Reacting to onReconnectListener is the supported way to do
|
|
2576
|
+
* that.
|
|
2526
2577
|
*
|
|
2527
|
-
*
|
|
2528
|
-
*
|
|
2529
|
-
*
|
|
2530
|
-
*
|
|
2578
|
+
* Concurrent calls are safe: each IQ carries its own unique id, responses
|
|
2579
|
+
* are dispatched per id, and the flag is set independently for each result.
|
|
2580
|
+
* Calling enableNotices() again before the previous callback fires is
|
|
2581
|
+
* therefore allowed — for example when a second reconnect arrives while the
|
|
2582
|
+
* first enable is still in flight.
|
|
2531
2583
|
*
|
|
2532
|
-
*
|
|
2533
|
-
*
|
|
2584
|
+
* If the server does not answer, the callback receives an error after a
|
|
2585
|
+
* timeout instead of never being called.
|
|
2586
|
+
*
|
|
2587
|
+
* TODO(2.25.0): make auto-enable SDK-internal — fire on initial connect and
|
|
2588
|
+
* on every reconnect. Spec & three-state matrix are tracked in the internal
|
|
2589
|
+
* 2.25.0 backlog (auto-enable notices).
|
|
2534
2590
|
*
|
|
2535
2591
|
* @memberof QB.chat
|
|
2536
2592
|
* @param {enableNoticesCallback} callback - Called with (error, result) on IQ result.
|
|
@@ -2569,7 +2625,10 @@ ChatProxy.prototype = {
|
|
|
2569
2625
|
* Returns the local Notice Feature subscription flag.
|
|
2570
2626
|
* @memberof QB.chat
|
|
2571
2627
|
* @return {Boolean} true after a successful enableNotices(), false otherwise.
|
|
2572
|
-
* Reset to false on
|
|
2628
|
+
* Reset to false on disconnect and whenever a new XMPP session is
|
|
2629
|
+
* established, so after a reconnect it reports false until the consumer
|
|
2630
|
+
* enables notices again. Not synchronized with the server: it reflects
|
|
2631
|
+
* what this client last requested, not the server's own state.
|
|
2573
2632
|
* @since 2.24.0
|
|
2574
2633
|
*/
|
|
2575
2634
|
isNoticesEnabled: function () {
|
|
@@ -2622,10 +2681,34 @@ ChatProxy.prototype = {
|
|
|
2622
2681
|
}
|
|
2623
2682
|
|
|
2624
2683
|
if (Utils.getEnv().browser) {
|
|
2625
|
-
|
|
2684
|
+
// [CROS-1061] Without the 4th argument Strophe never times the IQ out,
|
|
2685
|
+
// so a server that stays silent leaves the caller without any callback
|
|
2686
|
+
// at all — the application spins forever. On timeout Strophe calls
|
|
2687
|
+
// _onError(null), which reports a 'cancel' error and leaves the flag
|
|
2688
|
+
// untouched.
|
|
2689
|
+
//
|
|
2690
|
+
// Note: this covers "server does not answer". It does NOT cover
|
|
2691
|
+
// "socket died", because the timeout is an addTimedHandler and
|
|
2692
|
+
// connection.reset() (called from the DISCONNECTED branch) clears
|
|
2693
|
+
// timedHandlers. That case is covered by the consumer-side timeout.
|
|
2694
|
+
self.connection.sendIQ(iq, _onSuccess, _onError, NOTICE_IQ_TIMEOUT_MS);
|
|
2626
2695
|
} else {
|
|
2627
2696
|
// Node/NativeScript path: register callback in nodeStanzasCallbacks map.
|
|
2697
|
+
// This path does not go through sendIQ, so the timeout is ours to run.
|
|
2698
|
+
var noticeIqTimer = setTimeout(function () {
|
|
2699
|
+
// Drop the pending entry first: _onIQ only dispatches while the
|
|
2700
|
+
// entry exists, so a late answer after this point is ignored
|
|
2701
|
+
// instead of invoking the callback a second time.
|
|
2702
|
+
delete self.nodeStanzasCallbacks[iqParams.id];
|
|
2703
|
+
_onError(null);
|
|
2704
|
+
}, NOTICE_IQ_TIMEOUT_MS);
|
|
2705
|
+
|
|
2628
2706
|
self.nodeStanzasCallbacks[iqParams.id] = function (stanza) {
|
|
2707
|
+
// Must be first: otherwise a timely answer still leaves the timer
|
|
2708
|
+
// armed, and it would fire later and call the callback a second
|
|
2709
|
+
// time with an error.
|
|
2710
|
+
clearTimeout(noticeIqTimer);
|
|
2711
|
+
|
|
2629
2712
|
// The map handler receives the result/error stanza. Inspect type to dispatch.
|
|
2630
2713
|
var iqType = chatUtils.getAttr(stanza, 'type');
|
|
2631
2714
|
if (iqType === 'result') {
|
|
@@ -2954,6 +3037,20 @@ function MucProxy(options) {
|
|
|
2954
3037
|
this.nodeStanzasCallbacks = options.nodeStanzasCallbacks;
|
|
2955
3038
|
//
|
|
2956
3039
|
this.joinedRooms = {};
|
|
3040
|
+
|
|
3041
|
+
/**
|
|
3042
|
+
* [CROS-1061] Rooms carried across an explicit QB.chat.reconnect().
|
|
3043
|
+
*
|
|
3044
|
+
* reconnect() has to clear joinedRooms — the new session holds no presence
|
|
3045
|
+
* yet — but until now it dropped the list without keeping a copy, so the
|
|
3046
|
+
* re-join loop in _postConnectActions found nothing to restore and group
|
|
3047
|
+
* dialogs silently stopped receiving message-level notices.
|
|
3048
|
+
*
|
|
3049
|
+
* Written only by reconnect(), read and cleared once by _postConnectActions,
|
|
3050
|
+
* and cleared by disconnect() so one user's rooms can never be re-joined
|
|
3051
|
+
* from another user's JID.
|
|
3052
|
+
*/
|
|
3053
|
+
this._roomsToRejoin = [];
|
|
2957
3054
|
}
|
|
2958
3055
|
|
|
2959
3056
|
MucProxy.prototype = {
|