Alexander Mills
Alexander Mills

Reputation: 99960

How to pass WS connection socket from parent process to child process

There is an example here: https://github.com/websockets/ws/issues/154

In the parent we have:

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);

and in the child process we have:

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');
  });
});

my question: for my use-case, I would like the websocket server in the parent process, but allow the child process to write directly to the sockets of the WSS connections, is this possible?

Upvotes: 2

Views: 844

Answers (4)

anarchomeritocrat
anarchomeritocrat

Reputation: 9

In the node.js, with ws lib, Net.Socket, Http.Server and WebSocket.Server can be constructed from each other like a lego, with possibility of handling packets on every level of protocols hierarchy:

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 );

But only Net.Socket can be transferred to child process, so, in the child process you should also construct a HTTP and WebSocket servers for handle that Net.Socket

In case, when you want to handle TLS/SSL connection, you should in a parent process, also listen as Net.Server, on connections transfer Net.Socket to the child, and emit 'connection' event on the HTTPS server instance, constructed, using cert and key, which loaded from file, or received from parent process.

Note that in such architecture, you will not be able to handle data from new connections in the main process, but only accept new connections and immediately transfer new Net.Socket to the child process, so, the handshake logic should be placed ONLY in child process.

In theory, in the case of TLS/SSL, you can use different certificates inside different child processes

Upvotes: 1

Steffen Ullrich
Steffen Ullrich

Reputation: 123260

While it is at least on UNIX systems possible to send a plain TCP socket using IPC to another process, this is not possible for TLS connections as needed for WSS. This is because the TLS state is inside the user space of the process which has done the TLS handshake. This state cannot be simply serialized and transferred to another process since it is intertwined with various structures in the SSL library using pointers into the memory of the parent process.

If instead the TLS is not terminated in nodejs but (as common) in some reverse proxy in front of nodejs, then one has only to deal with plain TCP in which case propagating the socket to another process and doing the Websockets handshake inside this process is feasible.

Upvotes: 1

Rameshkumar
Rameshkumar

Reputation: 260

Hope this will help you.

When you call server.listen(...) in a worker, it serializes the arguments and passes the request to the master process. If the master process already has a listening server matching the worker's requirements, then it passes the handle to the worker. If it does not already have a listening server matching that requirement, then it will create one, and pass the handle to the child.

check here

Upvotes: 0

rveerd
rveerd

Reputation: 4006

The Node.js cluster module allows you to listen in the server process but have a worker (child) process handle the communication.

In cluster mode you call createServer() in the worker process but Node.js will actually create the listen socket in the master process. When a client connects, the socket will be transferred to a worker process to further handle the communication. Node.js uses a round-robin approach to select the next worker.

In the master process you can create new worker processes using cluster.fork(). This eventually calls child_process.fork().

Often you create a fixed number of worker processes, for example a worker process per CPU core. But you can create and destroy worker processes as you see fit.

Upvotes: 1

Related Questions