Skip to content
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

Support for auto connect when disconnect #6

Open
hientrandvt opened this issue Mar 1, 2017 · 9 comments
Open

Support for auto connect when disconnect #6

hientrandvt opened this issue Mar 1, 2017 · 9 comments
Assignees

Comments

@hientrandvt
Copy link

Could you support auto connect?
Many thanks.

@jhansche
Copy link
Contributor

@rogerhu that will reconnect only if you try to subscribe() while it's disconnected. It does not attempt any sort of auto-reconnect (either immediately, with a backoff, or with a connectivity listener that reconnects when the device regains network connectivity).

That said, you can write your own code that listens for network connectivity changes, and attempts to reconnect a LiveQueryClient when the device regains connectivity.

@rogerhu
Copy link
Contributor

rogerhu commented Mar 27, 2017

Yeah do you want to take a stab at exponential backoff code ? :)

@jhansche
Copy link
Contributor

That said, you can write your own code that listens for network connectivity changes, and attempts to reconnect a LiveQueryClient when the device regains connectivity.

^ That only helps if the disconnect happened as a result of the device losing connectivity. If the server goes down, there's no retry/reconnect.

I wonder if we can add some kind of generic retry handler to the Parse Android SDK, and leverage that here.

This does bring up another point though: the host app is never notified of any connect/disconnect events. So the app can't even know whether a subscribe() call was successful or not. And it won't know if the LQ server got disconnected for any reason.

I can't commit to working on a backoff handler right now, but if my schedule frees up today or tomorrow I'll follow up here.

@jhansche
Copy link
Contributor

This has become higher priority for my team, so I'm going to work on two fixes:

  1. Add listener callbacks for socket open/close/error, so the host app is not kept in the dark.
  2. Add a way to reconnect after a non-user-initiated disconnect (server went away).

@jhansche jhansche self-assigned this Mar 27, 2017
jhansche pushed a commit to wondrous-io/ParseLiveQuery-Android that referenced this issue Mar 27, 2017
This enables a partial fix/workaround for parse-community#6, which otherwise wouldn't even
be possible in its current state.

Future changes will allow the client to automatically reconnect when the
connection has been broken for any reason other than explicit disconnect().
jhansche pushed a commit to wondrous-io/ParseLiveQuery-Android that referenced this issue Mar 27, 2017
This enables a partial fix/workaround for parse-community#6, which otherwise wouldn't even
be possible in its current state.

Future changes will allow the client to automatically reconnect when the
connection has been broken for any reason other than explicit disconnect().
jhansche pushed a commit that referenced this issue Mar 27, 2017
This enables a partial fix/workaround for #6, which otherwise wouldn't even
be possible in its current state.

Future changes will allow the client to automatically reconnect when the
connection has been broken for any reason other than explicit disconnect().
@jhansche
Copy link
Contributor

I've managed to get this working in my own project, by using the above referenced callbacks.

  1. Our project has its own connectivity monitor, so we tap into that to reconnect the livequery clients when connectivity is regained (wifi off/on, for example). This handles auto-reconnect due to local connection changes.
    I'd like to add a way to monitor for local connection changes automatically, using the built-in com.parse.ConnectivityNotifier -- or at least a way to request automatic monitoring. Something like ParseLiveQueryClient#registerConnectivityMonitor(Context)
  2. When creating a new ParseLiveQueryClient instance, we also register a callback listener. When it receives onLiveQueryClientDisconnected() with userInitiated=false, it will schedule an automatic reconnect. This handles auto-reconnect due to a remote server issue (like LiveQuery server was restarted, etc)

Eventually I'd like both of those to be supported natively in this library. If nothing else, I can just create standalone listeners for that, and if you want that behavior, you can register them yourself, rather than expect the client (which is currently lightweight) to do all this stuff automatically for you.

@monajafi
Copy link

monajafi commented Apr 19, 2017

@jhansche
Thanks for your big efforts on this issue.
I got the first solution to how reconnect the client after regaining connectivity using BroadcastReceivers similar to what has been done here:
http://www.singhajit.com/notify-android-device-network-status-changes/
Also ConnectivityNotifier in parse is private which can not be used and it should be changed to public.
How should we schedule an automatic reconnect in case of server restart? Did you use cloud code or something else? any code on this will be appreciated .
By using your methods we will have a complete realtime offline first sync in parse server
best regard

@jhansche
Copy link
Contributor

@monajafi sorry for not seeing this sooner. The way we resolved that in our app was by using the com.parse.ParseLiveQueryClient.registerListener(ParseQueryLiveQueryClientCallbacks) method. In that onLiveQueryClientDisconnected() callback, when userInitiated == false, we assume it was an unexpected disconnect (like server restart or server crashed), and schedule a reconnect attempt to happen at some randomized delay (currently randomized between 2000 - 4000 ms). In the future, that can be made more clever with a randomized backoff, so that the 2nd or 3rd attempt continues to wait for longer periods of time before the reconnect.

Simplistic version:

client = this.newClient();
client.registerListener(this);
...

@Override
public void onLiveQueryClientDisconnected(ParseLiveQueryClient client, boolean userInitiated) {
    if (!userInitiated && isClientMonitored(client)) {
        long delay = DELAY_RECONNECT_LIVEQUERY + new Random().nextInt(DELAY_RECONNECT_LIVEQUERY);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(ClientsHandler.MSG_RECONNECT_LIVEQUERY, client), delay);
    }
}

And in the Handler callback for MSG_RECONNECT_LIVEQUERY, call client.reconnect()

@monajafi
Copy link

Thanks for providing your solution. I've solved this way:
I've checking for internet connectivity state every 10000 ms if it is connected also was already disconnected means ParseLiveQuery should be connected.

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

5 participants