javascriptwebsocketsockjs

WebSocket using sockjs-client and stompjs cannot connect if I do not connect immediately after client creation


I was trying to connect to the remote only one time when the page loaded and subscribe channels afterwards when necessary.

To ensure the code can be shared by different pages, I wrote the code (closure) as follows and export the function webSocket as this:

export function webSocket() {
  const socket = new SockJS(WebSocketEndPoint.RESOURCE_CONTROLLER);
  const stompClient = Stomp.over(socket);
  let isConnected = false;
  function subscribe(address, callback) {
    if (isConnected) {
      stompClient.subscribe(address, callback);
    } else {
      stompClient.connect({}, () => {
        isConnected = true;
        stompClient.subscribe(address, callback);
      });
    }
  };
  function subscribeRealtimeExecOutput(addr, callback){ 
      subscribe(addr, callback);
  }

  return {
    subscribeRealtimeExecOutput,
  };
}

And

Use it in other pages as follows:

import { webSocket } from '../../websocket/websocketService';

//in the constructor
this.subscriber = webSocket().subscribeRealtimeExecOutput;

//used when required
this.subscriber(pane.jobIdentifier, (data) => {
  console.log(data);
});

And I hope the connect method will only be run once within the same page and the subscriber will then subscribe different channels based on the connection.

But, it seems it won't work - the connection will not be set up and consequently the browser just prompt me about Opening Web Socket...

Anyone can help? Thank you so much for your help.

Sincerely, Hearen


Solution

  • After testing locally myself, I found out that after I create the client and directly connect to the server, everything just works like a charm. So I refactored my code subscribe as follows:

    function subscribe(address, callback) {
        if (isConnected) {
          stompClient.subscribe(address, callback);
        } else {
          stompClient = Stomp.over(socket);
          isConnected = true;
          stompClient.connect({}, () => {
            stompClient.subscribe(address, callback);
          }, () => {
            console.error('Sorry, I cannot connect to the server right now.');
          });
        }
      }
    

    In which if the connection is still not set up, I create the client again and directory set the isConnected and connect to the server.

    Later on, I am just too curious about what's going on and sought something interesting on this:

    http://jmesnil.net/stomp-websocket/doc/

    Once a STOMP client is created, it must call its connect() method to effectively connect and authenticate to the STOMP server.

    Besides

    But what happens if the connection fails? the connect() method accepts an optional error_callbackargument which will be called if the client is not able to connect to the server.

    And a post from stackoverflow, which further confirm my refactor

    I create a new instance of Stomp.Client since the current one has its Web Socket closed and there is no way to reopen a Web Socket once it it closed.