Comparing version 0.1.0-alpha.7 to 0.1.0-alpha.8
@@ -32,3 +32,3 @@ 'use strict'; | ||
module.exports = class Metacom { | ||
class Metacom { | ||
constructor(url) { | ||
@@ -117,2 +117,4 @@ this.url = url; | ||
} | ||
}; | ||
} | ||
module.exports = { Metacom }; |
@@ -8,8 +8,8 @@ 'use strict'; | ||
const common = require('@metarhia/common'); | ||
const WebSocket = require('ws'); | ||
const ws = require('ws'); | ||
const Semaphore = require('./semaphore.js'); | ||
const Channel = require('./channel.js'); | ||
const SHUTDOWN_TIMEOUT = 5000; | ||
const SHORT_TIMEOUT = 500; | ||
const LONG_RESPONSE = 30000; | ||
@@ -22,4 +22,2 @@ | ||
const sample = arr => arr[Math.floor(Math.random() * arr.length)]; | ||
const receiveBody = async req => { | ||
@@ -34,17 +32,19 @@ const buffers = []; | ||
class Server { | ||
constructor(config, { application }) { | ||
constructor(config, { application, Channel }) { | ||
this.config = config; | ||
this.application = application; | ||
this.Channel = Channel; | ||
this.channels = new Map(); | ||
const { ports, host, concurrency, queue } = config; | ||
const { host, balancer, protocol, ports, concurrency, queue } = config; | ||
this.semaphore = new Semaphore(concurrency, queue.size, queue.timeout); | ||
const { threadId } = worker; | ||
const port = ports[threadId - 1]; | ||
this.ports = config.ports.slice(1); | ||
const transport = threadId === 1 ? http : https; | ||
this.balancer = balancer && threadId === 1; | ||
const skipBalancer = balancer ? 1 : 0; | ||
this.port = this.balancer ? balancer : ports[threadId - skipBalancer - 1]; | ||
const transport = protocol === 'http' || this.balancer ? http : https; | ||
const listener = this.listener.bind(this); | ||
this.server = transport.createServer({ ...application.cert }, listener); | ||
this.ws = new WebSocket.Server({ server: this.server }); | ||
this.ws.on('connection', (connection, req) => { | ||
const channel = new Channel(req, null, connection, application); | ||
this.ws = new ws.Server({ server: this.server }); | ||
this.ws.on('connection', async (connection, req) => { | ||
const channel = await new Channel(req, null, connection, application); | ||
connection.on('message', data => { | ||
@@ -54,10 +54,12 @@ channel.message(data); | ||
}); | ||
this.server.listen(port, host); | ||
this.protocol = protocol; | ||
this.host = host; | ||
this.server.listen(this.port, host); | ||
} | ||
listener(req, res) { | ||
const { channels } = this; | ||
async listener(req, res) { | ||
const { channels, Channel } = this; | ||
let finished = false; | ||
const { method, url, connection } = req; | ||
const channel = new Channel(req, res, null, this.application); | ||
const { url, connection } = req; | ||
const channel = await new Channel(req, res, null, this.application); | ||
channels.set(connection, channel); | ||
@@ -79,23 +81,40 @@ | ||
if (url === '/api') { | ||
if (method !== 'POST') { | ||
channel.error(403); | ||
return; | ||
} | ||
receiveBody(req).then( | ||
data => { | ||
channel.message(data); | ||
}, | ||
err => { | ||
channel.error(500, err); | ||
} | ||
); | ||
if (this.balancer) { | ||
const host = common.parseHost(req.headers.host); | ||
const port = common.sample(this.config.ports); | ||
const { protocol } = this.config; | ||
channel.redirect(`${protocol}://${host}:${port}/`); | ||
return; | ||
} | ||
if (url.startsWith('/api')) this.request(channel); | ||
else channel.static(); | ||
} | ||
request(channel) { | ||
const { req } = channel; | ||
if (req.method === 'OPTIONS') { | ||
channel.options(); | ||
return; | ||
} | ||
if (req.method !== 'POST') { | ||
channel.error(403); | ||
return; | ||
} | ||
const body = receiveBody(req); | ||
if (req.url === '/api') { | ||
body.then(data => { | ||
channel.message(data); | ||
}); | ||
} else { | ||
if (url === '/' && !req.connection.encrypted) { | ||
const host = common.parseHost(req.headers.host); | ||
const port = sample(this.ports); | ||
channel.redirect(`https://${host}:${port}/`); | ||
} | ||
channel.static(); | ||
body.then(data => { | ||
const { pathname, searchParams } = new URL('http://' + req.url); | ||
const [, interfaceName, methodName] = pathname.split('/'); | ||
const args = data ? JSON.parse(data) : Object.fromEntries(searchParams); | ||
channel.rpc(-1, interfaceName, methodName, args); | ||
}); | ||
} | ||
body.catch(err => { | ||
channel.error(500, err); | ||
}); | ||
} | ||
@@ -116,2 +135,6 @@ | ||
}); | ||
if (this.channels.size === 0) { | ||
await timeout(SHORT_TIMEOUT); | ||
return; | ||
} | ||
await timeout(SHUTDOWN_TIMEOUT); | ||
@@ -118,0 +141,0 @@ this.closeChannels(); |
'use strict'; | ||
module.exports = require('./lib/client.js'); | ||
module.exports.Server = require('./lib/server.js'); | ||
const { Server } = require('./lib/server.js'); | ||
const { Metacom } = require('./lib/client.js'); | ||
module.exports = Metacom; | ||
module.exports.Server = Server; |
{ | ||
"name": "metacom", | ||
"version": "0.1.0-alpha.7", | ||
"version": "0.1.0-alpha.8", | ||
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>", | ||
@@ -48,10 +48,10 @@ "description": "Communication protocol for Metarhia stack with rpc, events, binary streams, memory and db access", | ||
"devDependencies": { | ||
"eslint": "^7.8.1", | ||
"eslint": "^7.12.1", | ||
"eslint-config-metarhia": "^7.0.1", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"metatests": "^0.7.2", | ||
"prettier": "^2.1.1" | ||
"prettier": "^2.1.2" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19467
527