diff --git a/net/js/package.json b/net/js/package.json index 135148cc438deb4b5196d16a6435366c2a5a2bc9..460025828764649f516ec005fddae1c3c6445bea 100644 --- a/net/js/package.json +++ b/net/js/package.json @@ -9,6 +9,7 @@ "author": "Nicolas Pope", "license": "ISC", "dependencies": { + "bops": "^1.0.0", "struct": "0.0.12", "uri-js": "^4.2.2", "ws": "^6.2.1" diff --git a/net/js/src/socket.js b/net/js/src/socket.js index 25e7050cc1b84f764cc6c24ff053bd6a2bc0193a..d051f87637fc060fdbdbdfded37b73c1d89be2ad 100644 --- a/net/js/src/socket.js +++ b/net/js/src/socket.js @@ -1,6 +1,7 @@ const net = require('net'); const ws = require('ws'); const urijs = require('uri-js'); +const binary = require('bops'); function Socket(uri) { let t = typeof uri; @@ -12,6 +13,7 @@ function Socket(uri) { 'close': [] }; + this.connected_ = false; this.buffer_ = new Buffer(0); if (t == "string") { @@ -19,19 +21,6 @@ function Socket(uri) { } else if (t == "object") { this._fromObject(uri); } - - // Attach handler depending on socket type - if (this.scheme_ = "websocket") { - if (this.socket_.addEventHandler) { - this.socket_.addEventHandler('message', event => { - dataHandler(event.data); - }); - } else { - this.socket_.on('message', dataHandler); - } - } else { - this.socket_.on('data', dataHandler); - } } Socket.prototype._fromURI = function(uri) { @@ -48,7 +37,7 @@ Socket.prototype._fromURI = function(uri) { } this._initWebsocket(); } else if (this.scheme_ == "tcp") { - this.socket_ = new net.Socket(uriobj.port, uriobj.host); + this.socket_ = net.connect(uriobj.port, uriobj.host); this._initTCPSocket(); } else { console.error("Invalid URI scheme for socket: ", this.scheme_); @@ -95,25 +84,33 @@ Socket.prototype._initWebsocket = function() { Socket.prototype._initTCPSocket = function() { let dataHandler = (data) => { - /*console.log('Received: ' + data); + console.log('Received: ' + data); this.buffer_ = Buffer.concat([this.buffer_, data]); if (this.buffer_.length >= 8) { - this.header_._setBuff(this.buffer_); - let size = this.header_.get('size'); + let size = binary.readUInt32LE(this.buffer_,0); + let service = binary.readUInt32LE(this.buffer_,4); - console.log("Message: " + this.header_.get('service')); + console.log("Message: " + service); // Do we have a complete message yet? - if (this.buffer_.length-4 >= size) { + if (size > 1024*1024*100) { + this.dispatch('error', ["invalid message size"]); + console.log("Message too big"); + } else if (this.buffer_.length-4 >= size) { // Yes, so dispatch console.log("Complete message found"); + this.dispatch(service, [size, binary.subarray(this.buffer_,8)]); } else { console.log("Incomplete message"); } - }*/ + } }; this.socket_.on('data', dataHandler); + this.socket_.on('connect', () => { + this.connected_ = true; + this.dispatch('open', []); + }); } Socket.prototype.isConnected = function() { @@ -122,7 +119,7 @@ Socket.prototype.isConnected = function() { Socket.prototype.on = function(name, f) { if (typeof name == "string") { - if (this.handlers.hasOwnProperty(name)) { + if (this.handlers_.hasOwnProperty(name)) { this.handlers_[name].push(f); } else { console.error("Unrecognised handler: ", name); @@ -135,6 +132,18 @@ Socket.prototype.on = function(name, f) { } } +Socket.prototype.dispatch = function(h, args) { + if (this.handlers_.hasOwnProperty(h)) { + let hs = this.handlers_[h]; + for (var i=0; i<hs.length; i++) { + hs[i].apply(this, args); + } + return true; + } else { + return false; + } +} + Socket.prototype.close = function() { this.socket_.destroy(); this.socket_ = null; diff --git a/net/js/test/socket_unit.js b/net/js/test/socket_unit.js index 21a68624bc8c6225eb1a8652375c69756f635bee..c7c104d198044e28fcce24600a544863a7d88ffd 100644 --- a/net/js/test/socket_unit.js +++ b/net/js/test/socket_unit.js @@ -1,44 +1,59 @@ const Socket = require('../src/socket.js'); const assert = require('assert'); const net = require('net'); +const binary = require('bops'); describe("Constructing a socket", function() { + let server; - let server = net.createServer(socket => { - console.log("Client connected"); + beforeEach(() => { + server = net.createServer(socket => { + console.log("Client connected"); + }); + server.listen(9000, 'localhost'); }); - server.listen(9000, 'localhost'); it("Connects to a valid tcp uri", function(done) { let sock = new Socket("tcp://localhost:9000"); - sock.on('connect', () => { + sock.on('open', () => { + console.log("OPEN"); assert.equal(sock.isConnected(),true); sock.close(); done(); }); }); - server.close(() => { console.log("Closed"); }); + afterEach(() => { + server.close(() => { console.log("Closed"); }); + server.unref(); + }); }); -describe("Receiving messages on a socket", function() { +describe("Receiving messages on a tcp socket", function() { + let server; - let server = net.createServer(socket => { - console.log("Client connected"); - server.write(Buffer.from('helloworld')); + beforeEach(() => { + server = net.createServer(socket => { + console.log("Client connected"); + socket.write(Buffer.from([8,0,0,0,44,0,0,0,23,0,0,0])); + }); + server.listen(9001, 'localhost'); }); - server.listen(9000, 'localhost'); - it("Connects to a valid tcp uri", function(done) { - let sock = new Socket("tcp://localhost:9000"); - sock.on(44, (data) => { + it("receives valid short message", function(done) { + let sock = new Socket("tcp://localhost:9001"); + sock.on(44, (size, data) => { // TODO Parse the data... + assert.equal(binary.readInt32LE(data,0), 23); console.log("Received data...."); - done(); sock.close(); + done(); }); }); - server.close(() => { console.log("Closed"); }); + afterEach(() => { + server.close(() => { console.log("Closed"); }); + server.unref(); + }); });