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.
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.
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:
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With