Reputation: 357
I have a relatively high level architecture question. My applications run on multiple JVMs on multiple physical nodes in a cluster. If I define a websocket endpoint so that it can be served by any of the JVMs how could I initiated a server initiated "send" message so that all appropriate connections across any JVM can send the message?
What I mean is if user A connection to JVM-A and user B connection to JVM-B and then an event on JVM-C occurs that requires user A and B to be notified how would that work? At first I was thinking of sharing the connection/session objects in distributed memory, but I dont think having that object will be enough since the physical connection is on a certain server?
Is there a more standard way to handle this problem?
Upvotes: 6
Views: 1333
Reputation: 8888
An idea borrowed from Phoenix framework:
You can introduce some sort of pub/sub (e.g. Redis). Whenever something interesting happens on one of the servers in the cluster, publish a notification to the pub/sub. All servers subscribe to that pub/sub. Whenever a server receives a notification from the pub/sub, it checks the websockets on itself, decide which ones should receive a message, convert the notification to a message, and send it to the clients.
The hard part is the single point of failure of the pub/sub server. You have to replicate it.
Upvotes: 2
Reputation: 474
You may create a queue and make your nodes read from this queue. The challenge than would be to know when to remove the message from the queue. Suggestion: Each node reads the message and multicast it for it's own connected sockets, than you stablish a time out for the message, this way each node should know that it has already sent that message, and if the message timed out, any node can remove it from the queue. Would that be possible in your case?
Upvotes: 1
Reputation: 721
Suggest creating a bean that is ApplicationScoped
(if JSF) or Singleton
if using CDI that subscribes to a multicast socket (preferrably on a network interface that's only LAN accessible). When one websocket initiates a 'send', it also dispatches a LAN message to the multicast group (possibly including the web socket message to be redispatched). Receiving beans should check if they dispatched the sent message (depends if multicast loopback was active) and discard anything they initiated themselves, but would otherwise re-dispatch the relevant message using their own active websockets once the LAN message is received on the multicast group.
Upvotes: 2