Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wildfly - Communication between 2 Websockets on separate nodes?

We are developing an application that will include some rudimentary chat/message passing functionality. The web application is deployed on Wildfly 8.x, and makes use of standard JavaEE 7 libraries (as opposed to an additional application framework like Spring) We're leveraging Websockets to accomplish this, as we need the push-to-browser functionality it provides. However, we're deploying this web application in a clustered/HA configuration. If UserA is connected to NodeA and passes in a message that is destined to UserB connected to NodeB, how do we do the transport of this message?

In a single-node configuration, the simple answer would be to maintain a static Map or List that has all of the Websockets and sessions, and route to the appropriate Websocket based on the message destination. But, with more than one node that obviously won't work because the static Map/List is per-JVM.

How would we go about accomplishing this goal? Would it be possible to use JMS and have each Websocket act as a JMS listener? What impact would this have on resource utilization or scalability and performance?

We're at a bit of a loss as to how to solve this problem, and would really appreciate any advice you can give.

like image 552
Shadowman Avatar asked May 23 '14 15:05

Shadowman


3 Answers

You can do this in two ways

1) You can create a separate push service on different web server, make publisher and subscriber listen to this service. Use this push service as broker, that is whenever publisher is ready with the data to push they will push it to this service then the broker gets the data broadcasts to all the subscribers.

2) You can create a JMS queue on a seperate JVM, make publisher and subscriber listen to this service. Use this JVM service as broker.

You can also use this service for other purposes also like securing the messages, maintaining sessions, store messages for future delivery when intended receiver is not available to receive the messages.

However the disadvantage of using the model is it will add one more maintenance overhead to your application setup.

like image 51
Hari Avatar answered Oct 26 '22 17:10

Hari


I suggest using a database as a synchronization point.
Imagine a single DB table with pending messages, each node queries it periodically and picks only messages for its active clients, delivers them and updates the table (and inserts newly received messages).

Advantages:

  • easy to implement
  • easy to configure (the same datasource on each node)
  • fast
  • super scalable
  • won't be an infrastructural nightmare
  • easy to monitor
  • transactional (as opposed to some cluster-wide cache)

The only complication is that you would have to come up with a good strategy of deciding when to query so that not to oversaturate the DB; for instance you may use a single JMS topic to signal other nodes that a new message arrived.
I know it doesn't seem as fancy as doing it with async messaging only but give it a thought!

like image 34
Yuri Avatar answered Oct 26 '22 17:10

Yuri


Simplest way is probably to use the built in cluster communication system, by doing so, you will remain horizontally scalable :

https://docs.jboss.org/author/display/WFLY8/HTTP+Services

http://www.jgroups.org/tutorial/html/ch02.html

if you don't have the message destination connection on the current node, just forward it to all other nodes of the cluster, the one managing the good connection will push it, others will ignore.

I never used this kind of features anyway, i suppose that multicast must be supported by the network.

like image 20
Gab Avatar answered Oct 26 '22 16:10

Gab