Mercurial > eldonilo > lightstring
comparison bosh.js @ 99:f14558915187
bosh support
author | Sonny Piers <sonny.piers@gmail.com> |
---|---|
date | Tue, 12 Jun 2012 19:44:53 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
98:6ec16b3e9cfc | 99:f14558915187 |
---|---|
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 })(); |