如何从父进程向子进程传递WS连接套接字

问题描述 投票:0回答:4

这里有一个例子: https://github.com/websockets/ws/issues/154

在父级中我们有:

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

const child = cp.fork('child.js');
const server = http.createServer();

server.on('upgrade', (request, socket) => {
  child.send({ headers: request.headers, method: request.method }, socket);
});

server.listen(8080);

在子进程中我们有:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ noServer: true });

process.on('message', (request, socket) => {
  wss.handleUpgrade(request, socket, undefined, (ws) => {
    ws.send('foo');
  });
});

我的问题:对于我的用例,我希望在父进程中使用 websocket 服务器,但允许子进程直接写入 WSS 连接的套接字,这可能吗?

node.js http sockets websocket node-websockets
4个回答
1
投票

虽然至少在 UNIX 系统上可以使用 IPC 向另一个进程发送普通 TCP 套接字,但对于 WSS 所需的 TLS 连接来说这是不可能的。这是因为 TLS 状态位于已完成 TLS 握手的进程的用户空间内。该状态不能简单地序列化并传输到另一个进程,因为它使用指向父进程内存的指针与 SSL 库中的各种结构交织在一起。

如果 TLS 不是在 Nodejs 中终止,而是(通常)在 Nodejs 前面的某些反向代理中终止,那么只需处理纯 TCP,在这种情况下,将套接字传播到另一个进程并在该进程内进行 Websockets 握手是可行的。


1
投票

Node.js 集群模块允许您在服务器进程中监听,但有一个工作(子)进程处理通信。

在集群模式下,您在工作进程中调用

createServer()
,但 Node.js 实际上会在主进程中创建监听套接字。当客户端连接时,套接字将被转移到工作进程以进一步处理通信。 Node.js 使用循环方法来选择下一个工作人员。

在主进程中,您可以使用

cluster.fork()
创建新的工作进程。这最终会调用
child_process.fork()

通常您会创建固定数量的工作进程,例如每个 CPU 核心一个工作进程。但您可以根据需要创建和销毁工作进程。


0
投票

希望这对您有帮助。

当您在工作线程中调用 server.listen(...) 时,它会序列化 参数并将请求传递给主进程。如果大师 进程已经有一个与工作进程匹配的监听服务器 要求,然后将句柄传递给工作人员。如果没有 已经有一个符合该要求的监听服务器,那么它 将创建一个,并将句柄传递给子级。

查看这里


0
投票

在node.js中,通过ws lib,Net.Socket、Http.Server和WebSocket.Server可以像乐高积木一样相互构建,并且可以在协议层次结构的每个级别上处理数据包:

server = http.createServer(handleHTTPLevel);

wss = new WSS({ server });
wss.on('connection', handleWSLevel);

netServer = net.createServer(function (socket){
  handleTCPLevel(socket)
  server.emit('connection', socket);
}).listen( listenPort );

但是只有 Net.Socket 可以传输给子进程,因此,在子进程中还应该构建一个 HTTP 和 WebSocket 服务器来处理 Net.Socket

如果您想要处理 TLS/SSL 连接,您应该在父进程中也作为 Net.Server 进行监听,在连接上将 Net.Socket 传输给子进程,并在 HTTPS 服务器实例上发出“连接”事件,使用从文件加载或从父进程接收的证书和密钥构造。

注意,在这样的架构中,你将无法在主进程中处理来自新连接的数据,而只能接受新连接并立即将新的 Net.Socket 传输给子进程,因此,握手逻辑应该放在它。

理论上,在 TLS/SSL 的情况下,您可以在不同的子进程中使用不同的证书

© www.soinside.com 2019 - 2024. All rights reserved.