How to check nodejs socket is exists on another nodejs server - node.js

I wants to setup a nodejs chat app on two servers, but my concern is that will node check that the user who wants to send messages on the socket is connected on different socket.
suppose nodejs1 is on server1 and listing on 3001 and nodejs2 is on server2 listing on 3002
user 1 is connected to 3001 and user 2 is connected to 3002
user 1 wants to send a message to user 2
user 1 and user 2 socket is stored on db
Is this communication can be possible ?

check it out if https://github.com/indutny/sticky-session can work out for you as if you will use socket.io
Socket.io is doing multiple requests to perform handshake and establish connection with a client. With a cluster those requests may arrive to different workers, which will break handshake protocol.
Sticky-sessions module is balancing requests using their IP address. Thus client will always connect to same worker server, and socket.io will work as expected, but on multiple processes!

Related

How to use Socket.io with Nginx load balancer?

I was going over this article: https://medium.com/#feritzcan/node-js-socket-io-1cde93315a7d, the section "CHAPTER 9 — NGINX Load Balancer", where it is said that:
Imagine you have 3 servers on ports 3000,3001,3002. An user connects to server through Nginx and its forwarded to server on port 3000. Then, socket connection between client and server:3000 is established. However, when client emit any event to server through Nginx, client is not guaranteed to be forwarded to the server:3000 again. Most of the time, it will be forwarded to server:3001 or server:3002 which doesn't recognize the client and will result in error.
In round-robin algorithm; requests are distributed sequentially among servers.
And then, below it is said that:
Ip hashing is a proxy algorithm like round-robin. The algorithm will always forward clients from the same ip to the same server. So, user will always connect the same server and be recognized.
Edit your config file again and set IP hashing this time
sudo nano /etc/nginx/sites-available/yourdomain.com
,upstream app_servers {
ip_hash;
server 142.93.111.111:3001;
server 142.93.111.111:3002;
server 142.93.111.111:3003;
….
…
…
After restarting Nginx, it will use IP hashing and will always forward clients to the same server that they were forwarded before.
Now my question here is: OK, I get it how the NGINX Load Balancer ensures that the same client will always be connected to the same server, but what about the frontend and the way the socket.io-client is created? For example, if we use server:3000 as the URL when creating the socket on the frontend side, does this means that every client will always be connected to the server:3000?
This somehow goes against the feature for distrusting the load between multiple servers, so I wonder If I am missing anything related.

Get Room object in other node in socket.io in multiple socket.io server environment

I have two socket io servers, and two clients are connected on different servers say, client 1 is connected to server 1 and client 2 is connected to server 2.
Now client 1 creates a room in its socket.io server i.e in server 1 and when client 2 tries to join that room it actually cannot find that room because that room is in server 1 and client 2 is trying to find the room in server 2 which is not created there.
Currently, I'm using a PostgreSQL adapter to route events to different clients connected on different servers. The events are passing successfully but client 2 is not able to join the room.
So how can I get the room information which is created on server 1 in the second socket.io server?
If there is any other way to do it. Please tell me.

Persist websocket connection object across the multiple server

I am using a websocket library on server for establishing socket connection.
https://github.com/websockets/ws
I have a more than one server in cluster, I want to know how can I use same socket connection object on another server in cluster.
And also I want to know what is the best option for webchat implementation native websocket or socket.io
You cannot use the same actual socket object across multiple servers. The socket object represents a socket connection between a client and one physical server process. It is possible to build a virtual socket object that would know what server its connection is on, send that server a message to then send out over the actual socket from that other server.
The socket.io/redis adapter is one such virtual ways of doing this. You set up a node.js cluster and you use the redis adapter with socket.io. It uses a central redis-based store to keep track of which serve process each physical connection is one. Then, when you want to send a message to a particular client from any of the server processes, you send that message through socket.io and it looks up for you in the redis database where that socket is connected, contacts that actual server and asks it to send the message to that particular client over the socket.io connection that is currently present on that other server process. Similarly, you can broadcast to groups of sockets and it will do all the work under the covers of making sure the message gets to the clients no matter which actual server they are connected to.
You could surely build something similar yourself for plain webSocket connections and others have built pieces of it. I'm not familiar enough with what exists out there in the wild to offer any recommendations for a plain webSocket. There plenty of articles on scaling webSocket servers horizontally which you can find with Google and read to get started if you want to do it with a plain webSocket.

socketio inter server communication with redis and haproxy

I'm working on a project which uses SocketIO and should be Horizontally scalable. Im using
A Load Balancer using HAProxy
Multiple Node Servers (2-4)
Database server(Redis and MongoDB)
I'm able to redirect my incoming Socket connections to Node servers using roundrobin method. Socket connection is stable and if I use socket.emit() I'm receiving the data. I'm also able to emit to the Other socket connection connected to the same Node server.
I'm facing issue in the following scenario:
User A connected to Node server 1 and User B connected to Node Server 2
My intention is to store the Socket data in redis
If User A wants to send some data to User B, how can I tell the Node server 2 to emit the data to User B from Node server 1
Please let me know how can I achieve this (with ref if possible).
Thanks in advance.
This scenario is a match for the case Pub/Sub of Redis.
If you haven't already, you should try Pub/Sub.
Have a look at socket.io Redis adapter. It should be exactly what you need.
clients() method in particular looks promising. Keep in mind, that socket.io creates a unique room for each client.

socket.io security - maybe allow only from specific domain?

I build a websocket (node.js + socket.io) service that will aggregate data on clients (resolution, clicks etc) and send to my admin (via websockets). However I have some concerns about security. On client's side my websocket server address is exposed like this:
var socket = new io.Socket('127.0.0.1', {'port': 3000});
so anyone can take that address and hit a milion requests (which will bring my server down).
How to protect my socket server? Maybe only allow socket connections from my domain (how)?
How to protect my socket server?
You can limit the number of concurrently connected clients. For example if there are 5000 actively connected clients through WebSockets, then new ones will be refused until there are some "free slots" for them.
Maybe only allow socket connections from my domain (how)?
Client (browser) connections doesn't have your domain as "origin".

Resources