So, I will try and explain this to the best of my ability:
I wrote a TCP server that accepts data from a wearable (type of gps bracelet), using net
in NodeJS
. TCP server has connections = {}
property, which contains all the connections, like this:
- Server accepts connection
- Device sends handshake packet, that contains
device id
- Socket is stored like:
connections[device_id] = socket
Same TCP server also has express
server which allows me to send data directly to the device using JSON post: curl -XPOST https://localhost:8080/send/device_id -d '{"command": "test"}'
Server parsers the url and writes to socket with connections[params.device_id].write()
This all works fine, when using pm2 start server.js
. I am able to track devices, accept and send data, etc.
The issue is, when I start the server using pm2 start -i 5 server.js
in cluster mode, device connections work okay, but express
part is giving me issues.
For example: when I use curl -XPOST https://localhost:8080/send/device_id -d '{"command": "test"}'
in 80% of the time, this will go to the wrong instance of server.js
, because there are five copies of server.js
running and each has express
server, and since PM2 manages everything, my request will hit the tcp
server where the given device_id
is connect in 1 out of 5 times. The way I understand it, PM2 starts 5 instances of server.js
and manages and balances the connections for tcp
and express
.
So, my question is, how should I manage this? Is there a way to tell PM2 to forward port 8080
to ALL running instances in a cluster? That way I could send single command to all instances, and in the instance, check if device_id is connected, and write to it's socket.
Is this possible, and if so, is it a good idea? If not, what is the right approach to this?
Hope I managed to explain
Regards
* EDIT *
It may not be clear from the initial question, but the socket
in question is passed from net.createServer
function, like
const net = require('net');
const PORT = 8181;
let connections = {}
const server = net.createServer((c) => {
//... device id parse
connections[device_id] = c;
});
server.listen(PORT, () => {
console.log('Server started on', PORT);
});