From e492ae974603ccf0191f0bfec18b65895c2f1f8d Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Wed, 3 Apr 2019 08:32:59 +0300 Subject: [PATCH] Initial javascript net and web-service functions --- net/js/package.json | 18 +++++ net/js/src/index.js | 0 net/js/src/socket.js | 160 +++++++++++++++++++++++++++++++++++++ net/js/test/socket_unit.js | 44 ++++++++++ web-service/package.json | 19 +++++ web-service/src/index.js | 25 ++++++ 6 files changed, 266 insertions(+) create mode 100644 net/js/package.json create mode 100644 net/js/src/index.js create mode 100644 net/js/src/socket.js create mode 100644 net/js/test/socket_unit.js create mode 100644 web-service/package.json create mode 100644 web-service/src/index.js diff --git a/net/js/package.json b/net/js/package.json new file mode 100644 index 000000000..1bc11f2cc --- /dev/null +++ b/net/js/package.json @@ -0,0 +1,18 @@ +{ + "name": "@ftl/net", + "version": "0.0.1", + "description": "P2P Network protocol for FT-Lab", + "main": "src/index.js", + "scripts": { + "test": "mocha test" + }, + "author": "Nicolas Pope", + "license": "ISC", + "dependencies": { + "struct": "0.0.12", + "uri-js": "^4.2.2" + }, + "devDependencies": { + "mocha": "^6.0.2" + } +} diff --git a/net/js/src/index.js b/net/js/src/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/net/js/src/socket.js b/net/js/src/socket.js new file mode 100644 index 000000000..25e7050cc --- /dev/null +++ b/net/js/src/socket.js @@ -0,0 +1,160 @@ +const net = require('net'); +const ws = require('ws'); +const urijs = require('uri-js'); + +function Socket(uri) { + let t = typeof uri; + + this.handlers_ = { + 'open': [], + 'data': [], + 'error': [], + 'close': [] + }; + + this.buffer_ = new Buffer(0); + + if (t == "string") { + this._fromURI(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) { + let uriobj = urijs.parse(uri); + + this.uri_ = uri; + this.scheme_ = uriobj.scheme; + + if (this.scheme_ == "ws") { + if (typeof WebSocket == "undefined") { + this.socket_ = new ws(uri); + } else { + this.socket_ = new WebSocket(uri); + } + this._initWebsocket(); + } else if (this.scheme_ == "tcp") { + this.socket_ = new net.Socket(uriobj.port, uriobj.host); + this._initTCPSocket(); + } else { + console.error("Invalid URI scheme for socket: ", this.scheme_); + } +} + +Socket.prototype._fromObject = function(sock) { + this.socket_ = sock; + + if (typeof WebSocket == "undefined") { + if (sock instanceof ws) this.scheme_ = "ws"; + else if (sock instanceof net.Socket) this.scheme_ = "tcp"; + else this.scheme_ = null; + } else { + if (sock instanceof WebSocket) this.scheme_ = "ws"; + else this.scheme_ = null; + } + + if (this.scheme_ == "ws") this._initWebsocket(); + else if (this.scheme_ == "tcp") this._initTCPSocket(); +} + +Socket.prototype._initWebsocket = function() { + let dataHandler = (data) => { + let size = binary.readUInt32LE(data, 0); + let service = binary.readUInt32LE(data, 4); + + console.log("Message", service); + if (this.handlers_.hasOwnProperty(service)) { + this.handlers_[service](binary.subarray(data, 8)); + } else { + console.error("No handler for service "+service); + } + }; + + if (this.socket_.addEventHandler) { + this.socket_.addEventHandler('message', event => { + dataHandler(event.data); + }); + } else { + this.socket_.on('message', dataHandler); + } +} + +Socket.prototype._initTCPSocket = function() { + let dataHandler = (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'); + + console.log("Message: " + this.header_.get('service')); + + // Do we have a complete message yet? + if (this.buffer_.length-4 >= size) { + // Yes, so dispatch + console.log("Complete message found"); + } else { + console.log("Incomplete message"); + } + }*/ + }; + this.socket_.on('data', dataHandler); +} + +Socket.prototype.isConnected = function() { + return this.connected_; +} + +Socket.prototype.on = function(name, f) { + if (typeof name == "string") { + if (this.handlers.hasOwnProperty(name)) { + this.handlers_[name].push(f); + } else { + console.error("Unrecognised handler: ", name); + } + } else if (typeof name == "number") { + if (this.handlers_[name] === undefined) this.handlers_[name] = []; + this.handlers_[name].push(f); + } else { + console.error("Invalid handler: ", name); + } +} + +Socket.prototype.close = function() { + this.socket_.destroy(); + this.socket_ = null; +} + +Socket.prototype._socket = function() { + return this.socket_; +} + +Socket.prototype.getURI = function() { + return this.uri_; +} + +Socket.prototype.asyncCall = function(name, cb /*, ...*/) { + +} + +Socket.prototype.send = function(id /*, ...*/) { + //this.socket_.write( +} + +module.exports = Socket; + diff --git a/net/js/test/socket_unit.js b/net/js/test/socket_unit.js new file mode 100644 index 000000000..21a68624b --- /dev/null +++ b/net/js/test/socket_unit.js @@ -0,0 +1,44 @@ +const Socket = require('../src/socket.js'); +const assert = require('assert'); +const net = require('net'); + +describe("Constructing a socket", function() { + + let server = net.createServer(socket => { + console.log("Client connected"); + }); + server.listen(9000, 'localhost'); + + it("Connects to a valid tcp uri", function(done) { + let sock = new Socket("tcp://localhost:9000"); + sock.on('connect', () => { + assert.equal(sock.isConnected(),true); + sock.close(); + done(); + }); + }); + + server.close(() => { console.log("Closed"); }); +}); + +describe("Receiving messages on a socket", function() { + + let server = net.createServer(socket => { + console.log("Client connected"); + server.write(Buffer.from('helloworld')); + }); + server.listen(9000, 'localhost'); + + it("Connects to a valid tcp uri", function(done) { + let sock = new Socket("tcp://localhost:9000"); + sock.on(44, (data) => { + // TODO Parse the data... + console.log("Received data...."); + done(); + sock.close(); + }); + }); + + server.close(() => { console.log("Closed"); }); +}); + diff --git a/web-service/package.json b/web-service/package.json new file mode 100644 index 000000000..ea4d7e8fc --- /dev/null +++ b/web-service/package.json @@ -0,0 +1,19 @@ +{ + "name": "@ftl/web-service", + "version": "0.0.1", + "description": "Web-service backend for FT-Lab systems", + "main": "src/index.js", + "directories": { + "test": "test" + }, + "scripts": { + "start": "node src/index.js", + "test": "mocha test" + }, + "author": "Nicolas Pope", + "license": "ISC", + "dependencies": { + "express": "^4.16.4", + "express-ws": "^4.0.0" + } +} diff --git a/web-service/src/index.js b/web-service/src/index.js new file mode 100644 index 000000000..42d7cfefb --- /dev/null +++ b/web-service/src/index.js @@ -0,0 +1,25 @@ +const express = require('express'); +const app = express(); +const expressWs = require('express-ws')(app); + +app.get('/', (req, res) => { + res.end(); +}); + +app.ws('/', (ws, req) => { + console.log("New web socket request"); + // SEND Handshake + ws.on('message', (msg) => { + console.log("Message", msg); + }); + ws.on('error', () => { + console.log("Error"); + }); + ws.on('close', () => { + console.log("Close"); + }); +}); + +console.log("Listening or port 3000"); +app.listen(3000); + -- GitLab