-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstrophe.rebind.js
128 lines (114 loc) · 4.87 KB
/
strophe.rebind.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
Strophe.addConnectionPlugin("rebind", {
/**
* Field: hasRebindFeature
*
* After connection attempt it shows if server support rebind feature
*/
hasRebindFeature: false,
/**
* Field: active
*
* Shows if rebind is enabled on this session
*/
active: false,
/** Function: rebind
* Restore previous session on server
*
* This call will estabilish connection to server and will try to restore previous session on server. If session
* restoration will not success (because session expired or server don't offer that functionality) connection status
* will change to CONNFAIL.
*
* @param jid Full JID of session to restore, it can be found as `connection.jid`
* @param sid Stream ID of previous session, it can be found as `connection.rebind.sid`
* @param callback Callback function that will be called on connection status change
*/
rebind: function(jid, sid, callback) {
this._rebind(jid, null, sid, callback, true);
},
/** Function: rebindOrConnect
* Restore previous session on server or create new session if restoration is not possible
*
* This call will estabilish connection to server and will try to restore previous session on server. If session
* restoration will not success (because session expired or server don't offer that functionality) new session will
* be created.
*
* @param jid Full JID of session to restore, it can be found as `connection.jid`
* @param pass Password that should be used to connect to server
* @param sid Stream ID of previous session, it can be found as `connection.rebind.sid`
* @param callback Callback function that will be called on connection status change
*/
rebindOrConnect: function(jid, pass, sid, callback) {
this._rebind(jid, pass, sid, callback, false);
},
_handleStreamStart: function(elem) {
this._conn.rebind.sid = elem.getAttribute("id");
return Strophe.Websocket.prototype._handleStreamStart.call(this, elem);
},
_connect_cb: function(req, cb, raw) {
this.rebind.hasRebindFeature = this.rebind.hasRebindFeature ||
req.getElementsByTagNameNS("p1:rebind", "rebind").length > 0;
return Strophe.Connection.prototype._connect_cb.apply(this, arguments);
},
_authenticate: function(mechanisms) {
if (!this.hasRebindFeature) {
if (this._onlyRebind)
this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "Rebind not available");
else
this._origAuthenticate.call(this._conn, mechanisms);
return;
}
var shandler = this._conn._addSysHandler((function(elem) {
this._conn.deleteHandler(fhandler);
this.sid = this._sid;
this.active = true;
this._conn.authenticated = true;
this._conn._changeConnectStatus(Strophe.Status.ATTACHED, null);
return false;
}).bind(this), null, "rebind", null, null);
var fhandler = this._conn._addSysHandler((function(elem) {
this._conn.deleteHandler(shandler);
if (this._onlyRebind)
this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "Rebind failure");
else
this._origAuthenticate.call(this._conn, mechanisms);
return false;
}).bind(this), null, "failure", null, null);
this._conn.send($build('rebind', {
xmlns: "p1:rebind"
}).c("jid", {}).t(this._conn.jid)
.up()
.c("sid", {}).t(this._sid).tree());
},
_rebind: function(jid, pass, sid, callback, onlyRebind) {
this._sid = sid;
this._onlyRebind = onlyRebind;
if (sid) {
if (!this._origAuthenticate) {
this._origAuthenticate = this._conn.authenticate;
this._conn.authenticate = this._authenticate.bind(this);
}
} else if (onlyRebind) {
this._conn._changeConnectStatus(Strophe.Status.CONNFAIL, "Rebind not active");
return;
}
this._conn.connect(jid, pass, callback);
},
statusChanged: function(status, condition) {
var _this = this;
if (this.hasRebindFeature && status == Strophe.Status.CONNECTED) {
var push = $iq({type: "set"}).c("push", {xmlns: "p1:push"})
.c("keepalive", {max: "30"}).up()
.c("session", {duration: "1"});
this._conn.sendIQ(push, function() {
_this.active = true;
}, function() {
_this.active = false;
});
}
},
init: function(conn) {
this._conn = conn;
this._conn._proto._handleStreamStart = this._handleStreamStart;
this._conn._connect_cb = this._connect_cb;
},
});