Huy Quoc
Huy Quoc

Reputation: 11

What does it matter if there are many nodejs emitter listeners?

I'm writing a TCP server application using NodeJS. However, each socket runs on a separate child-process (server.on("connection")). To send messages to specific clients, I used Emitter, and each socket generates its own listener (on clientID). So if there are 10000 connected devices, the application will create 10000 listeners. This looks terrible. What dangers will this pose? I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code. Update: Have any idea to send message to specific client without add custom listeners?

Upvotes: 0

Views: 184

Answers (1)

freakish
freakish

Reputation: 56587

However, each socket runs on a separate process.

Why would you do that? The core idea behind NodeJS is to run things in an event loop. Single threaded, yes, but asynchronous.

This looks terrible. What dangers will this pose?

It is terrible. The biggest issue is that you sacrifice a lot of resources. You not only spawn thousands of processes but you also spawn lots of emitters. So first of all this means lots of RAM eaten. Secondly this means degraded performance due to process context switch, which typically is slower than user space switch. Assuming your machine will even allow you to spawn so many processes.

I can't find a solution to send a message from one client to another in the TCP protocol writing NodeJS code.

I assume you have a TCP server, two connected clients and client A wants to send message to client B. Is that correct? TCP by itself won't do that for you. You need some protocol on top of it. For example:

  1. Client connects to the server. At this point the client is not logged in and cannot do anything except for authentication.
  2. Client authenticates. It sends (username, password) pair to the server. The server validates the pair. The server keeps a global mapping {"<username>": [sockets]} and adds newly authenticated client to that mapping.
  3. Client A wants to send a message to client B. So it sends data of the form {"type": "direct", "destination": "clientB", "data": "hello B"}. The server parses the message and forwards it to the appropriate client (taken from the global mapping).

In case when you want to broadcast the message you send say {"type":"broadcast", "data": "hello all"} kind of message. The server then parses it, it loops through all connected clients (found in the global mapping) and forwards the message to each client.

Of course you also need some framing of packets. Since TCP is a stream, then it doesn't really understand messages and where one starts and the other ends. Dumping things to JSON is a half of the problem. Because then you have to send this JSON over the network and the other side has to know how many bytes it has to read. One way is to prefix each message with, say, 2 bytes that tell the other side how long the message is.

Btw you may want to consider using socket.io (or some other lib) that take care of some of those tedious details for you.

Upvotes: 0

Related Questions