Socket io on ELB, need to connect to all instances of application servers
Asked Answered
M

1

7

Socket based event push architecture I have a socket server application written on node js, hosted on Amazon EBS(Elastic bean stalk) which is managed by load balancer

Clients connects to the socket and pass specified id, say event_id my application creates room with name "event_event_id" and join the room. Different clients have different "event_id"

A lambda function connects to the socket and emits an event named "event_push" to the application with necessary data such as event_id

Whenever my socket application(in one of the instances in EBS) detects a push event with event_id, it broadcast the pushed data to all members of the room "event_event_id", thus all members gets notified of the event

clients can connect any of the servers, decided by load balancer and sticky sessions can maintain the connection

Now my problem: Is there a way to emit the "event_push" to only the server having a room named "event_event_id"

Qn: Is there a way to emit an event to all instances of the servers in EBS? OR Qn: Is there any alternate solutions?

Marten answered 13/3, 2017 at 11:12 Comment(1)
Possible solution: A central subscribe/publish server which can have persistent connection which can receive the event details. The socket servers can subscribe to the central server so that, when ever there is an event, will be pushed to all subscribed socket servers over the persistent connection.Marten
A
0

What you can do is you can use Redis or mongoDb for saving some information about in your case event_event_id. You can save this information in data storage for example sample doc

{
   _id : ObjectId,
   userId : 23,
   event : event_event_id,
   server : 1
},
{
   _id : ObjectId,
   userId : 23,
   event : event_event_id,
   server : 2
}

Now what this will do is you will have the information that which event belongs to which server. Now if loadbalancer send request of server1 to server 2 and server 2 doesnt recognize that request you can create a communication channel between the servers(you can use socketio, microservice or anything) and redirect that request to server 1 so it can trigger that particular socket event.

You have to delete the socket id from mongo or redis when disconnect event is triggered.

Alcaic answered 18/3, 2017 at 16:21 Comment(5)
1. My servers are kick started by Elastic Bean Stalk, you will never know which server is up and which server is down, or when a new server is initialized. So, communication between servers is out of question in this scenario.Marten
2. You will never know which user is connected to which server, this is about socket connection from browser to server, the connection is persistent, and the client(Browsers) cannot establish connection to a particular server due to 2 reasons. a) The servers are not up always, but managed by EBS and client(Browsers) dont have any information about the servers . b)Connection is determined by Elastic Load Balancer(ELB)Marten
Also events are not restricted to any user or any other entity, so I cannot do binding as you suggested.Marten
it is stated in the socket io documentation server can only emit on sockets which are generated from that server.. So if server is going down then that connection is gone you cant emit on those sockets. Yes i know client doesnt know on which server request is going to land you have to attach some identifier at server end may be in server config file or as a envoirment variable.Alcaic
The problem is even you will never know which server is running and what is the identity of the server since the instances are managed by Elstic Bean Stalk of Amazon. EBS can fire and terminate server instances based on healthMarten

© 2022 - 2024 — McMap. All rights reserved.