使用衍生工具处理节点安全Web套接字

时间:2018-07-10 14:39:26

标签: javascript node.js sockets websocket

我正在一个需要节点服务器处理安全websocket连接的项目中。一个要求是每个websocket都是它自己的Node进程。

我的原型代码全都在一个过程中,它使我可以手动将原始套接字升级到SSL和WebSocket。这似乎有效。我以这种方式对其进行了原型设计,以便可以在创建原始套接字与应用SSL和WebSocket包装器之间插入spawn()函数。

(server.js)

#!/usr/bin/env node
'use strict';

const net = require('net');
const tls = require('tls');
const fs = require('fs');
const https = require('https');
var WebSocketServer = require('ws').Server;


const port = 3014;

const options = {
    key: fs.readFileSync('certs/server/server.key'),
    cert: fs.readFileSync('certs/server/server.crt'),
    ca: fs.readFileSync('certs/ca/ca.crt'),
    requestCert: false,
    rejectUnauthorized: false
};


const wss = new WebSocketServer({
    noServer: true
});


var httpsServer = https.createServer( options, (req,res) => {
    console.log("https");
})
.on('connection', function(socket) {
    console.log('connection https'); })
.on('upgrade',    function(req,sock,head) {
    console.log('upgrade https');
    wss.handleUpgrade(req, sock, head, (client) => {
        console.log("wss upgraded");
    });
})
.on('request',    function(req,res) {
    console.log('request https');
})
.on('clientError',function(ex,sock) {
    console.log('cliError https'); console.dir(ex);
});


var server = net.createServer((socket) => {
    console.log("net_createServer()");
})
.on('connection', function(socket)
{
    console.log('insecure connection');
    httpsServer.emit('connection',socket);
})
.listen(port, function() {
    console.log('server listening on port ' + port + '\n');
});

这是控制台输出,显示了正在触发的事件。通过原始套接字创建的httpsServer看来,它已经一路成功升级到安全Web套接字。

server listening on port 3014
net_createServer()
insecure connection
connection https
upgrade https
wss upgraded

现在,如果我将此代码分成两个程序并插入spawn(),send(),process.on.message代码,则在触发httpsServer对象上的连接事件后,它将挂起。

(parent.js)

#!/usr/bin/env node
'use strict';

const net = require('net');
const cp = require('child_process');

const port = 3014;


var server = net.createServer((socket) => {
    console.log("net_createServer()");
})
.on('connection', function(socket)
{
    console.log('insecure connection');

    var child = cp.spawn('node', ['./child.js'], {detached: true, stdio: [0,1,2,'ipc']});

    child.send("socket",socket);
    child.disconnect();
    child.unref();
})
.listen(port, function() {
    console.log('server listening on port ' + port + '\n');
});

(child.js)

#!/usr/bin/env node
'use strict';

const tls = require('tls');
const fs = require('fs');
const https = require('https');
var WebSocketServer = require('ws').Server;

const options = {
    key: fs.readFileSync('certs/server/server.key'),
    cert: fs.readFileSync('certs/server/server.crt'),
    ca: fs.readFileSync('certs/ca/ca.crt'),
    requestCert: false,
    rejectUnauthorized: false
};


const wss = new WebSocketServer({
    noServer: true
});


var httpsServer = https.createServer( options, (req,res) => {
    console.log("https");
})
.on('connection', function(socket) {
    console.log('connection https');
})
.on('upgrade', function(req,sock,head) {
    console.log('upgrade https');
    wss.handleUpgrade(req, sock, head, (client) => {
        console.log("wss upgraded");
    });
})
.on('request', function(req,res) {
    console.log('request https');
})
.on('clientError', function(ex,sock) {
    console.log('cliError https');
    console.dir(ex);
});


process.on('message', (msg,socket) => {
    console.log("received message, msg=" + msg);
    httpsServer.emit('connection',socket);
});

这是这套程序的控制台输出...

server listening on port 3014
net_createServer()
insecure connection
received message, msg=socket
connection https

如您所见,child.js程序在获取带有套接字的消息并尝试将该套接字发送到httpsServer之后挂起。 httpsServer会触发“连接”,但永远不会触发“升级”事件。如果我让它坐在那里足够长的时间,则httpsServer会触发具有以下内容的“ clientError”事件...

cliError https
Error: TLS handshake timeout
    at TLSSocket._handleTimeout (_tls_wrap.js:592:22)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at TLSSocket.emit (events.js:208:7)
    at TLSSocket.Socket._onTimeout (net.js:410:8)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)

我似乎无法弄清楚为什么它作为单个进程起作用,但是在父进程和子进程之间划分代码却无法协商SSL连接。我猜我的代码在某种程度上是错误的,但是我没有看到它。

0 个答案:

没有答案