# HG changeset patch # User Sonny Piers # Date 1339511727 -7200 # Node ID 11e38a9bfe3894b5f83122a93022323e9740ec74 # Parent 646695bde8e98c610d21ff6a6f232e5609378948 multi-transport is now possible diff --git a/lightstring.js b/lightstring.js --- a/lightstring.js +++ b/lightstring.js @@ -150,46 +150,35 @@ Lightstring.Connection.prototype = { if (!this.service) return; //TODO: error - // Standard - if (typeof(WebSocket) === 'function') - this.socket = new WebSocket(this.service, 'xmpp'); - // Safari - else if (typeof(WebSocket) === 'object') - this.socket = new WebSocket(this.service, 'xmpp'); - // Old Gecko - else if (typeof(MozWebSocket) === 'function') { - this.socket = new MozWebSocket(this.service, 'xmpp'); + function getProtocol(aURL) { + var a = document.createElement('a'); + a.href = aURL; + return a.protocol.replace(':', ''); } - // No known WebSocket support - else { - return; //TODO: error - } + var protocol = getProtocol(this.service); + + if (protocol.match('http')) + this.connection = new Lightstring.BOSHConnection(this.service); + else if (protocol.match('ws')) + this.connection = new Lightstring.WebSocketConnection(this.service); - var Conn = this; - this.socket.addEventListener('open', function() { - //FIXME: Opera/Safari WebSocket implementation doesn't support sub-protocol mechanism. - //if (this.protocol !== 'xmpp') - //return; //TODO: error + this.connection.connect(); + + var that = this; - var stream = Lightstring.stanzas.stream.open(Conn.jid.domain); - this.send(stream); + this.connection.once('open', function() { + var stream = Lightstring.stanzas.stream.open(that.jid.domain); + that.connection.send(stream); var stanza = { XML: stream }; - Conn.emit('output', stanza); - }); - this.socket.addEventListener('error', function(e) { - Conn.emit('disconnecting', e.data); - //TODO: error + that.emit('output', stanza); }); - this.socket.addEventListener('close', function(e) { - Conn.emit('disconnected', e.data); - }); - this.socket.addEventListener('message', function(e) { - var stanza = new Lightstring.Stanza(e.data); + this.connection.on('stanza', function(stanza) { + var stanza = new Lightstring.Stanza(stanza); //FIXME: node-xmpp-bosh sends a self-closing stream:stream tag; it is wrong! - Conn.emit('input', stanza); + that.emit('input', stanza); if (!stanza.DOM) return; @@ -205,49 +194,49 @@ Lightstring.Connection.prototype = { var nodes = stanza.DOM.getElementsByTagName('mechanism'); for (var i = 0; i < nodes.length; i++) stanza.mechanisms.push(nodes[i].textContent); - Conn.emit('mechanisms', stanza); + that.emit('mechanisms', stanza); } //XMPP features else { //TODO: stanza.features - Conn.emit('features', stanza); + that.emit('features', stanza); } } else if (name === 'challenge') { - Conn.emit('challenge', stanza); + that.emit('challenge', stanza); } else if (name === 'failure') { - Conn.emit('failure', stanza); + that.emit('failure', stanza); } else if (name === 'success') { - Conn.emit('success', stanza); + that.emit('success', stanza); } //Iq callbacks else if (name === 'iq') { var payload = stanza.DOM.firstChild; if (payload) - Conn.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza); + that.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza); var id = stanza.DOM.getAttribute('id'); - if (!(id && id in Conn.callbacks)) + if (!(id && id in that.callbacks)) return; var type = stanza.DOM.getAttribute('type'); if (type !== 'result' && type !== 'error') return; //TODO: warning - var callback = Conn.callbacks[id]; + var callback = that.callbacks[id]; if (type === 'result' && callback.success) - callback.success.call(Conn, stanza); + callback.success.call(that, stanza); else if (type === 'error' && callback.error) - callback.error.call(Conn, stanza); + callback.error.call(that, stanza); - delete Conn.callbacks[id]; + delete that.callbacks[id]; } else if (name === 'presence' || name === 'message') { - Conn.emit(name, stanza); + that.emit(name, stanza); } }); }, @@ -288,7 +277,7 @@ Lightstring.Connection.prototype = { //FIXME this.socket.send(stanza.XML); (need some work on Lightstring.Stanza) var fixme = Lightstring.DOM2XML(stanza.DOM); stanza.XML = fixme; - this.socket.send(fixme); + this.connection.send(fixme); this.emit('output', stanza); }, /** diff --git a/websocket.js b/websocket.js new file mode 100644 --- /dev/null +++ b/websocket.js @@ -0,0 +1,43 @@ +'use strict'; + +(function() { + Lightstring.WebSocketConnection = function(aService) { + this.service = aService; + }; + Lightstring.WebSocketConnection.prototype = new EventEmitter(); + Lightstring.WebSocketConnection.prototype.connect = function() { + // Standard + if (typeof(WebSocket) === 'function') + this.socket = new WebSocket(this.service, 'xmpp'); + // Safari + else if (typeof(WebSocket) === 'object') + this.socket = new WebSocket(this.service, 'xmpp'); + // Old Gecko + else if (typeof(MozWebSocket) === 'function') + this.socket = new MozWebSocket(this.service, 'xmpp'); + // No WebSocket support + else + return; //TODO: error + + var Conn = this; + this.socket.addEventListener('open', function() { + //FIXME: Opera/Safari WebSocket implementation doesn't support sub-protocol mechanism. + //if (this.protocol !== 'xmpp') + //return; //TODO: error + Conn.emit('open') + }); + this.socket.addEventListener('error', function(e) { + Conn.emit('disconnecting', e.data); + //TODO: error + }); + this.socket.addEventListener('close', function(e) { + Conn.emit('disconnected', e.data); + }); + this.socket.addEventListener('message', function(e) { + Conn.emit('stanza', e.data); + }); + }, + Lightstring.WebSocketConnection.prototype.send = function(aStanza) { + this.socket.send(aStanza); + } +})(); \ No newline at end of file