We have a design where the front end connects to backend nodes by Websockets.
Consider an example where
- Frontend node 1 (connects websocket) —–> server node1
- Then server node1 cache the session id(session id 1) in the in memory of server node1 and goes off and does some activity.( sends some events to kafka etc)
- Then downstream services do some action (consume events from kafka) and return a response to a redis stream
- This time a new server node (server node2) can pick up the event from redis stream and has to send the response to that sessionid (session id 1) but since it does not have the webconnection details it ignores the event.
- Only server node 1 is able to send response to that event because it has websocket connection details of session id 1
Is there a way for server node 1 to serialise the session id 1 and websocket connection details to a redis cache and when the server node 2 (as mentioned in step 4) picks up the redis stream even also reads the redis cache and desiarilise session 1 websocket connection and send the response to frontend node 1
IS THIS EVVEN possible
I have read many many articles and could not find any answer. All articles say that it is challenging but there is no place which says how to do it
Please can i get some help in this issue
We are using spring-messaging package and hence i tried to serialise SimpMessagingTemplate object so that i can deserialise it back in the server node 2 for us to read the websocket connection
But it failed to serialise the object. May be i am missing something.
SimpMessagingTemplate does not implement Serialisable interface
I need a solution to achieve the decoupling of websocket connection at the backend node (server node 1 to server node 2)
2
Answers
TCP connection is identified by source IP, source port, destination IP, destination port.
So your servers have to have same IP address. It is possible in theory, but very very very impractical.
Definitely impossible with just Java. You will need to hack into your OS TCP stack and create specialized router.
solution
What you need is middle man.
Router will handle websocket connection with client.
It is not possible to serialise a socket connection and reuse it on another server.
Even if you find a way to serialise/deserialise an Object, you cannot revive a TCP connection. Reviving would essentially mean creating a new socket connection.
What you should instead do is have a socket holding server where the connection is established and have different workers that then process the data. Once the results are available, use the same socket-holding server to send the message to the client.
An alternative approach would be to use a notification service like Firebase Cloud Messaging (FCM).