Skip to content

LiveQuery socket not reconnecting on resume from sleep in mobile #585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dpatel20 opened this issue Jun 17, 2018 · 22 comments
Closed

LiveQuery socket not reconnecting on resume from sleep in mobile #585

dpatel20 opened this issue Jun 17, 2018 · 22 comments

Comments

@dpatel20
Copy link

I have created a Web App use the Parse backend which utilises Parse's LiveQuery (Websockets).

Whilst testing on mobile devices, I have noticed that after a long(ish) sleep the LiveQuery events don't seem to get through. Best as I can tell/understand, the browser is closing (?) the websocket.

Behind the scenes, I know the Parse JS SDK implements an exponential backoff automatic reconnect.

Is there a way to instantly auto connect on the browser window getting focus?

I tried a quick hack in the JS SDK as follows in the LiveQuery 'open' function

      if (firstTime) {
        $(window).on('focus', function () {
          console.log("Window got focus");
          this.attempts = 0;
          console.log(_this4.state)
          if (_this4.state !== CLIENT_STATE.CONNECTED)
            _this4._handleReconnect();
        });
        firstTime = false;
      }

However, this does not seem to work (at least not consistently). If I remove the check on the CONNECTED status, then it seems to work but then I end up with multiple sockets open (I know as I have a toast popup that is activated on live updates -- without the CONNECT check I get two popups instead of one). So, does that suggest that the Parse SDK is not aware the connection is broken? How I can I force a check?

@dpatel20
Copy link
Author

After debugging further, I've seen that the state is CONNECTED so I can only guess it has not yet updated its state. Javascript is running as my debug code fires on focus. I further tried doing a close and resubscribe:

_this4.socket.close();
_this4.resubscribe();

From this, I found that the close would not fire for exactly 1min (I output some timestamps to the HTML). I cannot find where this 1min timeout comes from...any ideas?

@dpatel20
Copy link
Author

I'm using this to log my findings...hope someone can help:

  • If I do nothing (i.e. keep parse.js as original), I can see that after a sleep (>10min) the readyState is OPEN. And, after ~1.5mins the LiveQuery I send is seen by the mobile browser. Is this something peculiar to WebSockets on Android browsers? If it's saying connected, then I'd expect an immediate update. (PS: I checked the Parse server logs and nothing shows a disconnect).

  • If I do the close() followed by the resubscribe(), in the server logs I see the disconnect immediately when the close() is called. But the on close event is not seen browser for exactly 1min. And then the resubscribe() occurs immediately after.

@flovilmart
Copy link
Contributor

I’m not sure it is related to the JS SDK itself. Perhaps there are workarounds that we could implement. Also, where lis your parse-server deployed?

@dpatel20
Copy link
Author

dpatel20 commented Jun 18, 2018

I am using Back4App, Parse Server 2.7.1.

I agree, I don't think it is an issue with the SDK...I was just using the SDK to debug/hack to try to find a workaround.

@flovilmart
Copy link
Contributor

Possibly also related to a seeverside connection configuration. Did you try with a pure JS websocker client without the parse JS SDK?

@dpatel20
Copy link
Author

I have contacted back4app for some help...awaiting further feedback.

I have no idea how to test with a JS websocket client...you mean use something like socket.io to connect to the Parse server and see if I get the same issue? Could you help as to how to do this?

@dpatel20
Copy link
Author

I'm starting to think it might be my phone or browser!!...not seen the issue on another phone and tablet.

@flovilmart
Copy link
Contributor

@dpatel20 that's something to consider too :)

@dpatel20
Copy link
Author

@flovilmart Seems to be occurring in other browsers and devices (to different extents/frequencies) --- all Android based. With the original code (without my hacks), it eventually seems to kick back into life.

Any suggestions of how I can work around this (or reduce the time to reconnect)?

@flovilmart
Copy link
Contributor

I’m not sure at this point. Is there littérature around the reconnections problems, like with socketIO or else?

@dpatel20
Copy link
Author

I have done some more testing and taken logcats on my Android phone and various debug messages added. I can see that the connection is actually closed and the reconnect mechanism kicks in. But then it sits in the 'open' (i.e. trying to re-open the socket) state as there is no network.

When I resume the device, it can take a few secs to reconnect but it does reconnect. I was testing fairly soon after unlocking and saw that it was missing the event. If I wait a few seconds and then fire the event, then all is good.

@flovilmart
Copy link
Contributor

flovilmart commented Jun 22, 2018 via email

@dpatel20
Copy link
Author

I should note that I had to reduce the backoff in generateInterval(). I changed it to be:

return Math.random() * k * 2000;

With the original setup I had a connection timeout error in the logcat.

@flovilmart
Copy link
Contributor

@dpatel20 is the back off configuration worth an addition to the SDK so the issue can be worked around?

@dpatel20
Copy link
Author

Do you mean being able to pass your own backoff function to the SDK?

@dpatel20 dpatel20 reopened this Jun 24, 2018
@flovilmart
Copy link
Contributor

Yep somehow when you setup the liveQuery client

@dpatel20
Copy link
Author

Hmmm...I'm a bit concerned that maybe a lot more complicated than it first seems (at least to me).

The generateInterval() function is not part of the LiveQueryClient class. If it was, then maybe the generateInterval could be an option in the constructor. But then that seems like quite a change for an issue only I seem to have come across?!

@flovilmart
Copy link
Contributor

Yeah perhaps, my concern is that you’re able to ship something that works, with a potential workaround

@dpatel20
Copy link
Author

Well, this is frustrating now...I've gone back to the original generateInterval() and no longer seeing the timeout issue. I need to do more testing to figure out what's going on. :(

@flovilmart
Copy link
Contributor

Haha, indeed!

@flovilmart
Copy link
Contributor

Should we close this one then? Feel free to reopen if needed

@dpatel20
Copy link
Author

Agreed...close for now. If I find why I got the timeout error mentioned above, then I'll reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants