JSteunou / webstomp-client

Stomp client over websocket for browsers
Apache License 2.0
299 stars 59 forks source link

Implement a reconnect option #16

Open mschipperheyn opened 8 years ago

mschipperheyn commented 8 years ago

There is no really great way to reconnect available it seems.

I'm currently implementing a timeout which recreates the client after a failure. That just seems like a very poor approach. stomp should have some kind of autoreconnect.

yeyu456 commented 8 years ago

Yep.I Agree.For now I try to do it by myself.You can refer to this reconnect websocket implement .

JSteunou commented 8 years ago

@mschipperheyn I actually do the same, but I dont know if it's should really be part of this lib. Pleased everyone on this feature would mean having a ton of options like delay, maxReconnectAttempt, ... things like that. Maybe this should be more like a plugin or wrapper around the stomp-client. The stomp-client is more just a JS implementation of STOMP protocol over websocket, dedicated to frames encode / decode.

mschipperheyn commented 8 years ago

Thanks for the reference @yeyu456

bfwg commented 8 years ago

My implementation, try to reconnect every 1 second after disconnected.

let ws = new WebSocket(socketUrl);
let client = webstomp.over(ws);
client.connect({}, (frame) => {
  successCallback();
}, () => {
  reconnect(socketUrl, successCallback);
});

function reconnect(socketUrl, successCallback) {
  let connected = false;
  let reconInv = setInterval(() => {
    ws = new WebSocket(socketUrl);
    client = webstomp.over(ws);
    client.connect({}, (frame) => {
      clearInterval(reconInv);
      connected = true;
      successCallback();
    }, () => {
      if (connected) {
        reconnect(socketUrl, successCallback);
      }
    });
  }, 1000);
}
pdeva commented 8 years ago

@bfwg in your error handler, you need to add connected = false otherwise reconnect will be called exponential times since more than 1 error can be thrown from a connection.

bfwg commented 8 years ago

@pdeva I have updated the implementation thanks to @teaegg

function connectAndReconnect(socketUrl, successCallback) {
    ws = new WebSocket(socketUrl);
    client = webstomp.over(ws);
    client.connect({}, (frame) => {
    successCallback();
  }, () => {
    setTimeout(() => {
      this.connectAndReconnect(socketUrl, successCallback);
    }, 1000)
  });
}

connectAndReconnect('ws//:xxxx:4321', () => { })

Looks good now?

mschipperheyn commented 8 years ago

There are better ways to do this I think. I adapted some reconnection library I found in the wild that has a kind of "dying" algorithm to not keep pinging needlessly.

ipluser commented 5 years ago

This is a good issue, as @JSteunou said "stomp-client is more just a JS implementation of STOMP protocol over WebSocket", that sounds like rights.

So we can wrap WebSocket using some library like @yeyu456 reconnecting-WebSocket.

But, what should the stomp-client do? the stomp-client also need to reconnect.

I think we can provide a good way to reconnect the stomp-client, e.g.

The WebSocket Wrapper can provide a hook method that gives another can watch reconnect event.

// the socket provide a `reconnect` hook method to add listen reconnect event
// if socket reconnect, then invoke the listeners
const socket = WebSocketReconnecter('ws://....')

// if stomp-client find the `socket` has hook method, then stomp-client add a listener to do reconnect inside the code
stompClient = webstomp.over(socket, {
  reconnect: 'reconnect'  // String (name for hook method) or Function
})

stompClient.connect({}, () => {
  // todo
}, () => {
  // todo
})