Forum Stats

  • 3,726,656 Users
  • 2,245,235 Discussions
  • 7,852,337 Comments

Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

WebSocket broadcast over cluster

WP v.2
WP v.2 Member Posts: 240 Blue Ribbon

Hi all,

I know this isn't strictly ADF, so if there's a better forum for this please let me know. I have a requirement where when a user makes a change to a record, there should be a push notification of the change to all users currently looking at that record. I wrote a WebSocket to handle this and it worked great. However, when I deployed it to a clustered environment, it appears that broadcasting messages only worked per managed server (i.e. if a user makes a change from one managed server, the push notifications only go to users on that same managed server and none of the other ones in the cluster).

I read that coherence could be a solution but I don't think management is willing to pay for it. Is there any way to broadcast to users across an entire cluster?

Here's my code for reference:

@ServerEndpoint(value = "/notify/{request-id}")
public class RequestWebSocket {
    private static final long IDLE_TIMEOUT = 30 * 60 * 1000;
    private static final String REQUEST_ID_PATH_PARAM = "request-id";
    
    @OnOpen
    public void openConnection(Session session) {
        session.setMaxIdleTimeout(IDLE_TIMEOUT);
    }    
    
    @OnClose
    public void closedConnection(Session session) {
        
    }
    
    @OnMessage
    public void messageReceived(Session session, String message) {
        String requestId = session.getPathParameters().get(REQUEST_ID_PATH_PARAM);
        
        for (Session _session : session.getOpenSessions()) {
            try {
                String _requestId = _session.getPathParameters().get(REQUEST_ID_PATH_PARAM);
                                
                /* Send message only to clients viewing changed request */
                if(requestId.equals(_requestId) && _session.isOpen() && !session.equals(_session)) { System.out.println("WEBSOCKET: sending");
                    _session.getBasicRemote().sendText(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }        
    }
    
    @OnError
    public void error(Session session, Throwable t) { 
        throw new RuntimeException(t);
    }
}


I'm on WebLogic 12.2.1.4.

Thanks,

Bill

Best Answer

  • Timo Hahn
    Timo Hahn Senior Principal Technical Consultant - Oracle ACE Director Member, Moderator Posts: 36,950 Red Diamond
    Accepted Answer

    Well, this is a common problem. You can look at https://tsh.io/blog/how-to-scale-websocket/ which describes the possible solutions. In the end, you'll need to implement something like a Publisher - Subscriber approach, where each of your nodes subscribes to a channel and passes it to the connected clients. If you send a message you don't do it directly, but you publish it and each server subscribing to the channel sends it out to its clients.


    Timo


Answers

  • Timo Hahn
    Timo Hahn Senior Principal Technical Consultant - Oracle ACE Director Member, Moderator Posts: 36,950 Red Diamond
    Accepted Answer

    Well, this is a common problem. You can look at https://tsh.io/blog/how-to-scale-websocket/ which describes the possible solutions. In the end, you'll need to implement something like a Publisher - Subscriber approach, where each of your nodes subscribes to a channel and passes it to the connected clients. If you send a message you don't do it directly, but you publish it and each server subscribing to the channel sends it out to its clients.


    Timo


Sign In or Register to comment.