horizon icon indicating copy to clipboard operation
horizon copied to clipboard

Manually reconnecting the web client

Open lirbank opened this issue 7 years ago • 8 comments

Server version: 2.0.0-beta-7 Client version: 2.0.0-beta-7

Not sure if I am doing this the right way but I can't seem to reconnect to the server after a temporary disconnect. Even though the client can't reconnect on it own, it should be possible to reconnect manually without refreshing the browser. Am I missing something or does it not work?

I run the code below and then close the server and start it again.

Example client code:

let message = {
  text: "What a beautiful horizon!",
  datetime: new Date(),
  author: "@dalanmiller"
}

let horizon = Horizon();
let chat = horizon("messages");
let isConnected = false;
let handle;

document.addEventListener("DOMContentLoaded", function(event) {
  document.querySelector('button').addEventListener('click', e => {
    console.log('CLICK');
    chat.store(message);
  });

  chat.watch().subscribe(docs => console.log('DOCUMENTS', docs.length));

  horizon.status(s => {
    console.log('status', s);
  });

  horizon.onReady(s => {
    if (handle) {
      clearInterval(handle);
    }
  });

  horizon.onSocketError(e => {
    console.log('socket error', e);
    //horizon.disconnect();
    //horizon = null;

    handle = setInterval(() => {
      console.log('RECONNECTING');
      //horizon = Horizon();
      //horizon.connect();
      chat.watch().subscribe((docs) => {console.log(docs.map(e => e.text))});
    }, 10000);
  });
});

Console: image

lirbank avatar Aug 21 '16 21:08 lirbank

Please note, the production release 1.1.3 has the same issue (with slightly different error messages if I remember correctly).

lirbank avatar Aug 22 '16 20:08 lirbank

This is due to the statuses being implemented by a BehaviorSubject, which will replay old states. This is good if you want to ensure you don't miss any states, but it's bad if you ever want to get rid of them.

Right now I'd suggest not manually reconnecting by simply emitting the query again, since there is likely other state that's not being cleaned up. It's best for now to just create a new horizon instance

deontologician avatar Aug 22 '16 20:08 deontologician

Thanks! But how do I "just create a new horizon instance"? I tried a lot of things but only got it working again after a page reload...

Edit: (as you can see in my code I tried multiple ways to disconnect from horizon and recreate the instance again, but it didn't help)

lirbank avatar Aug 22 '16 21:08 lirbank

Oh, never mind, got it working!

I just forgot to re-init the collection chat = horizon("messages"); after I created the new instance. This works for now. Thanks!

lirbank avatar Aug 22 '16 21:08 lirbank

Actually, I'm going to try getting this into 2.0.0, since even if you can't seamlessly reconnect, the experience here of reconnecting and re-issuing your queries is pretty bad and most everyone is going to run into reconnection needs. I don't think it should be too hard to fix

deontologician avatar Aug 22 '16 21:08 deontologician

Put this together and it seems to work properly:

let horizon;
let chat;
let handle;
let message = {text: 'What a beautiful horizon!'};

let connect = function () {
  console.log('CONNECTING');

  horizon = Horizon();
  horizon.status(s => console.log('status', s));

  horizon.onReady(s => {
    if (handle) {
      clearInterval(handle);
      handle = null;
    }
  });

  horizon.onSocketError(e => {
    console.log('socket error', e);
    if (! handle) handle = setInterval(connect, 5000);
  });

  chat = horizon('messages');
  chat.watch().subscribe(docs => console.log('DOCUMENT COUNT', docs.length));
};

document.addEventListener('DOMContentLoaded', function(event) {
  // Init
  connect();

  document.querySelector('button').addEventListener('click', e => {
    console.log('CLICK');
    chat.store(message);
  });
});

EDIT:

  1. But it will not work for React Native as the socket errors, etc, can't be caught properly. So will be awesome to have a fix for that.

  2. Another related issue, it is very hard to restart the server when the client is trying to reconnect. The server crashes on start so I have to try multiple times before I get it up and running again - will post a separate issue about that.

lirbank avatar Aug 22 '16 21:08 lirbank

beautiful, thanks for the example code

deontologician avatar Aug 22 '16 22:08 deontologician

Alright, I've been working on this for 3 days, can't seem to figure out what's going on, so I'm bumping this to 2.x.x

deontologician avatar Aug 25 '16 04:08 deontologician