From d289cd062df371da4cfe639616fc0c4293712988 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Thu, 4 Apr 2019 15:50:21 +0300 Subject: [PATCH] Basic working js tcp socket for ftlnet --- net/js/package.json | 1 + net/js/src/socket.js | 51 ++++++++++++++++++++++---------------- net/js/test/socket_unit.js | 45 ++++++++++++++++++++++----------- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/net/js/package.json b/net/js/package.json index 135148cc4..460025828 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 25e7050cc..d051f8763 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 21a68624b..c7c104d19 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(); + }); }); -- GitLab