Mercurial > eldonilo > lightstring
comparison transports/bosh.js @ 100:3e124209821a
move bosh.js and websocket.js to transports/
| author | Sonny Piers <sonny.piers@gmail.com> |
|---|---|
| date | Tue, 12 Jun 2012 19:46:52 +0200 |
| parents | |
| children | c06ec02217ee |
comparison
equal
deleted
inserted
replaced
| 99:f14558915187 | 100:3e124209821a |
|---|---|
| 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 })(); |
