99
|
1 'use strict';
|
|
2
|
|
3 (function() {
|
|
4 Lightstring.BOSHConnection = function(aService) {
|
|
5 this.service = aService;
|
|
6 this.rid = 1337;
|
|
7 this.currentRequests = 0;
|
|
8 this.maxHTTPRetries = 5;
|
|
9 this.maxRequests = 2;
|
|
10 this.queue = [];
|
|
11 };
|
|
12 Lightstring.BOSHConnection.prototype = new EventEmitter();
|
|
13 Lightstring.BOSHConnection.prototype.open = function() {
|
|
14 var that = this;
|
|
15
|
|
16 var attrs = {
|
|
17 wait: '60',
|
|
18 hold: '1',
|
|
19 to: 'yuilop',
|
|
20 content: 'text/xml; charset=utf-8',
|
|
21 ver: '1.6',
|
|
22 'xmpp:version': '1.0',
|
|
23 'xmlns:xmpp': 'urn:xmpp:xbosh',
|
|
24 };
|
|
25
|
|
26 this.request(attrs, null, function(data) {
|
|
27 that.emit('open');
|
|
28 that.sid = data.getAttribute('sid');
|
|
29 that.maxRequests = data.getAttribute('maxRequests') || that.maxRequests;
|
|
30 });
|
|
31
|
|
32
|
|
33 this.on('in', function(stanza) {
|
|
34 if (stanza.localName === 'success') {
|
|
35 that.request({
|
|
36 'xmpp:restart': 'true',
|
|
37 'xmlns:xmpp': 'urn:xmpp:xbosh'
|
|
38 })
|
|
39 }
|
|
40 })
|
|
41 };
|
|
42 Lightstring.BOSHConnection.prototype.request = function(attrs, children, aOnSuccess, aOnError, aRetry) {
|
|
43 // if (children && children[0] && children[0].name === 'body') {
|
|
44 // var body = children[0];
|
|
45 // }
|
|
46 // else {
|
|
47 // var body = new ltx.Element('body');
|
|
48 // if (children) {
|
|
49 // if(util.isArray(children))
|
|
50 // for (var k in children)
|
|
51 // body.cnode(children[k]);
|
|
52 // else
|
|
53 // body.cnode(children);
|
|
54 // }
|
|
55 // }
|
|
56
|
|
57 var body = '<body rid="' + this.rid++ + '" xmlns="http://jabber.org/protocol/httpbind"/>';
|
|
58 var body = Lightstring.XML2DOM(body);
|
|
59
|
|
60 //sid
|
|
61 if (this.sid)
|
|
62 body.setAttribute('sid', this.sid);
|
|
63
|
|
64 //attributes on body
|
|
65 for (var i in attrs)
|
|
66 body.setAttribute(i, attrs[i]);
|
|
67
|
|
68 //children
|
|
69 for (var i in children)
|
|
70 body.appendChild(children[i]);
|
|
71
|
|
72
|
|
73
|
|
74 var retry = aRetry || 0;
|
|
75
|
|
76 var req = new XMLHttpRequest();
|
|
77 req.open('POST', this.service);
|
|
78
|
|
79
|
|
80 // req.upload.addEventListener("progress", updateProgress, false);
|
|
81 // req.upload.addEventListener("load", transferComplete, false);
|
|
82 // req.upload.addEventListener("error", transferFailed, false);
|
|
83 // req.upload.addEventListener("abort", transferCanceled, false);
|
|
84
|
|
85 // req.addEventListener("progress", updateProgress, false);
|
|
86 // req.addEventListener("load", transferComplete, false);
|
|
87 // req.addEventListener("error", transferFailed, false);
|
|
88 // req.addEventListener("abort", transferCanceled, false);
|
|
89
|
|
90 var that = this;
|
|
91 // req.responseType = 'document';
|
|
92 req.addEventListener("load", function() {
|
|
93 if (req.status < 200 || req.status >= 400) {
|
|
94 that.emit('error', "HTTP status " + req.status);
|
|
95 that.emit('close');
|
|
96 return;
|
|
97 }
|
|
98 that.currentRequests--;
|
|
99
|
|
100 var body = this.response;
|
|
101 that.emit('rawin', body);
|
|
102 var bodyEl = Lightstring.XML2DOM(body);
|
|
103 that.processResponse(bodyEl)
|
|
104 if (aOnSuccess)
|
|
105 aOnSuccess(bodyEl);
|
|
106
|
|
107 }, false);
|
|
108 // req.on('error', function(error) {
|
|
109 // if (retry < that.maxHTTPRetries) {
|
|
110 // that.request(attrs, children, aOnSuccess, aOnError, ++retry);
|
|
111 // }
|
|
112 // else {
|
|
113 // that.emit('close');
|
|
114 // that.emit('error', error);
|
|
115 // if (aOnError)
|
|
116 // aOnError(error);
|
|
117 // }
|
|
118 // });
|
|
119 // this.emit('rawout', body.toString());
|
|
120
|
|
121 for(var i = 0; i < body.children.length; i++) {
|
|
122 var child = body.children[i];
|
|
123 that.emit('out', child);
|
|
124 }
|
|
125 this.emit('rawout', Lightstring.DOM2XML(body))
|
|
126
|
|
127 req.send(Lightstring.DOM2XML(body));
|
|
128 this.currentRequests++;
|
|
129 };
|
|
130 Lightstring.BOSHConnection.prototype.send = function(aData) {
|
|
131 if (!aData) {
|
|
132 var el = '';
|
|
133 }
|
|
134
|
|
135 else if(typeof aData == 'string') {
|
|
136 try {
|
|
137 var el = Lightstring.XML2DOM(aData);
|
|
138 }
|
|
139 catch(e) {
|
|
140 console.log(e);
|
|
141 console.log(aData);
|
|
142 }
|
|
143 }
|
|
144 else {
|
|
145 var el = aData.root();
|
|
146 }
|
|
147
|
|
148 var that = this;
|
|
149
|
|
150 this.queue.push(el);
|
|
151
|
|
152 setTimeout(this.mayRequest.bind(this), 0)
|
|
153
|
|
154 };
|
|
155 Lightstring.BOSHConnection.prototype.end = function(stanzas) {
|
|
156 var that = this;
|
|
157
|
|
158 stanzas = stanzas || [];
|
|
159 if (typeof stanzas !== 'array')
|
|
160 stanzas = [stanzas];
|
|
161
|
|
162 stanzas = this.queue.concat(stanzas);
|
|
163 this.queue = [];
|
|
164 this.request({type: 'terminate'}, stanzas,
|
|
165 function(err, bodyEl) {
|
|
166 that.emit('end');
|
|
167 that.emit('close');
|
|
168 delete that.sid;
|
|
169 });
|
|
170 };
|
|
171 Lightstring.BOSHConnection.prototype.processResponse = function(bodyEl) {
|
|
172 if (bodyEl && bodyEl.children) {
|
|
173 for(var i = 0; i < bodyEl.children.length; i++) {
|
|
174 var child = bodyEl.children[i];
|
|
175 this.emit('in', child);
|
|
176 }
|
|
177 }
|
|
178 if (bodyEl && bodyEl.getAttribute('type') === 'terminate') {
|
|
179 var condition = bodyEl.getAttribute('condition');
|
|
180 this.emit('error',
|
|
181 new Error(condition || "Session terminated"));
|
|
182 this.emit('close');
|
|
183 }
|
|
184 };
|
|
185 Lightstring.BOSHConnection.prototype.mayRequest = function() {
|
|
186 var canRequest =
|
|
187 this.sid && (this.currentRequests === 0 || ((this.queue.length > 0 && this.currentRequests < this.maxRequests))
|
|
188 );
|
|
189
|
|
190 if (!canRequest)
|
|
191 return;
|
|
192
|
|
193 var stanzas = this.queue;
|
|
194 this.queue = [];
|
|
195 //~ this.rid++;
|
|
196
|
|
197 var that = this;
|
|
198 this.request({}, stanzas,
|
|
199 //success
|
|
200 function(data) {
|
|
201 //if (data)
|
|
202 //that.processResponse(data);
|
|
203
|
|
204 setTimeout(that.mayRequest.bind(that), 0);
|
|
205
|
|
206 },
|
|
207 //error
|
|
208 function(error) {
|
|
209 that.emit('error', error);
|
|
210 that.emit('close');
|
|
211 delete that.sid;
|
|
212 }
|
|
213 );
|
|
214 };
|
|
215 })(); |