From 06dc3feddd1b44385ab060f4410a42fa0a3e7ed3 Mon Sep 17 00:00:00 2001 From: Pierre Guilleminot Date: Sun, 17 Feb 2013 18:44:44 +0100 Subject: [PATCH] WIP: chrome-udp transport for Chrome extension --- lib/network/transport/chrome-udp.js | 85 +++++++++++++++++++++++++++++ lib/network/transport/udp.js | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 lib/network/transport/chrome-udp.js diff --git a/lib/network/transport/chrome-udp.js b/lib/network/transport/chrome-udp.js new file mode 100644 index 0000000..4f0d222 --- /dev/null +++ b/lib/network/transport/chrome-udp.js @@ -0,0 +1,85 @@ +var StateEventEmitter = require('../../util/state-eventemitter'), + csock = (chrome.socket || chrome.experimental.socket); + +var UDPChrome = module.exports = StateEventEmitter.extend({ + + initialize: function(server_name, options) { + this.supr(); + this._listening = false; + this._socket = null + this._addr = '127.0.0.1'; + this._port = parseInt(options.port, 10) || 8000; + }, + + connect: function() { + this._socket = csock.create('udp', { onEvent: this.listener.bind(this) }, this.onCreate.bind(this)); + }, + + onCreate: function(createInfo) { + this._socket = createInfo; + if (createInfo.socketId > 0) { + csock.connect(createInfo.socketId, this._addr, this._port, this.onConnect.bind(this)); + } + }, + + onConnect: function() { + this.iam = this._socket.peerAddress + ':' + this._socket.peerPort; + this.setState('connected', this.iam); + }, + + disconnect: function() { + this._listening = false; + this._handler = null; + this._context = null; + csock.disconnect(this._socket.socketId); + this.setState('disconnected'); + }, + + send: function(dst, message) { + if (this.stateIsNot('connected')) { + throw new Error('ChromeUDP transport layer not connected.'); + } + var addr = dst.split(':'), + self = this; + this._stringToArrayBuffer(message, function(buff) { + csock.sendTo(self._socket.socketId, buff, addr[1], addr[0], function() {}); + }); + }, + + listen: function(fn, context) { + if (this.stateIsNot('connected')) { + throw new Error('ChromeUDP transport layer not connected.'); + } + this._listening = true; + this._handler = fn; + this._context = context; + }, + + listener: function() { + if (!this._listening) { return; } + var self = this; + csock.recvFrom(this._socket.socketId, function(infos) { + self._arrayBufferToString(infos.data, function(msg) { + self._handler.call(self._context || self, { + dst : this.iam, + src : infos.address + ':' + infos.port, + msg : msg + }); + }); + }); + }, + + _arrayBufferToString = function(buf, callback) { + var bb = new Blob([new Uint8Array(buf)]); + var f = new FileReader(); + f.onload = function(e) { callback(e.target.result); }; + f.readAsText(bb); + }, + + _stringToArrayBuffer = function(str, callback) { + var bb = new Blob([str]); + var f = new FileReader(); + f.onload = function(e) { callback(e.target.result); }; + f.readAsArrayBuffer(bb); + } +}); diff --git a/lib/network/transport/udp.js b/lib/network/transport/udp.js index 4b0802c..8bcde28 100644 --- a/lib/network/transport/udp.js +++ b/lib/network/transport/udp.js @@ -30,7 +30,7 @@ var UDPTransport = module.exports = StateEventEmitter.extend({ send: function(dst, message) { if (this.stateIsNot('connected')) { - throw new Error('SimUDP transport layer not connected.'); + throw new Error('UDP transport layer not connected.'); } if (!(message instanceof Buffer)) { message = new Buffer(message);