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