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

Handling loss of websocket connection #70

Open
chelliwell opened this issue Sep 10, 2019 · 10 comments
Open

Handling loss of websocket connection #70

chelliwell opened this issue Sep 10, 2019 · 10 comments
Milestone

Comments

@chelliwell
Copy link
Contributor

(Me again lol)
An area I'm concerned about is if a subscription websocket gets disconnected - loss of network, server restart etc.
I will be supplying an intermediate library for people to write their own 'as simple as possible' client app for receiving specific subscription messages from my server, and I would prefer not to burden them with reconnection headaches. - i.e. have either my library or [ideally!] SAHB.GraphQLClient deal with retrying on first subscribe, and with reconnecting if the websocket goes down after that.
I see that OnDisconnected() is empty, so maybe it's 'work in progress' - but it's quite a key area for me which would be great to see enhanced.
I appreciate that it might not be an easy one!

@sahb1239
Copy link
Owner

The WebSocket class does not have any Connect, however ClientWebSocket does have a Connect method.

Therefore reconnection should be implemented in GraphQLSubscriptionWebSocketClient possible by providing a new event in the IGraphQLSubscriptionClient which could be called on the empty method OnDisconnected(). The two classes GraphQLSubscriptionWebSocketClient and GraphQLSubscriptionClient are seperated because other WebSocket implementations should be supported for example the one I'm using in the test project.

In order to reconnect I also think I should resend all the OperationTypes with the type GQL_START (start) such that the operations will continue to receive data?

So the initial idea of how to support this could be:

  • Event Disconnected on IGraphQLSubscriptionClient
  • Method Reconnect/ReInitilize (or some other name) on IGraphQLSubscriptionClient
  • Configuration of number of retries on GraphQLSubscriptionWebSocketClient
  • Handle the Disconnect event in GraphQLSubscriptionWebSocketClient

Do you have any suggrestions to this?

@chelliwell
Copy link
Contributor Author

I'm afraid you're definitely over-stretching my C# skills there! So I'm afraid I can't really offer anything on how to achieve it - happy to try anything out though and see how it fits with me as a 'user'.
The main needs I see are to (ideally) automatically try to re-establish the socket and subscription, and to have any unhandleable events fed back to the app.

@chelliwell
Copy link
Contributor Author

The main needs I see are to (ideally) automatically try to re-establish the socket and subscription, and to have any unhandleable events fed back to the app.

And if the re-connect could use a progressive backoff interval.... ;)

@chelliwell
Copy link
Contributor Author

chelliwell commented Sep 17, 2019

By the way, you may need/want to watch out for the situation of StartListen in GraphQLSubscriptionClient catching an exception e.g. from the app's DataReceived handler - currently it just calls OnDisconnected.
Should perhaps do this only on catching exception from ConfigureAwait, rather than from OnMessageReceived too? Maybe some finer levels of try/catch in between StartListen and the app's handler - I wouldn't have thought the library needs to care about the latter? ("I simply gave you the data - I'm not going to do change what I'm doing just because you failed to process it successfully")

@sahb1239
Copy link
Owner

Eventhandlers should generally don't throw exceptions. But you are right the library should handle the exception instead of just calling OnDisconnected.

@chelliwell
Copy link
Contributor Author

Just coming from the point-of-view of a scruffy library user - quite possibly me lol.

@sahb1239
Copy link
Owner

Would you create a PR for this change? :)

@chelliwell
Copy link
Contributor Author

chelliwell commented Sep 17, 2019 via email

@sahb1239
Copy link
Owner

Yep I think it should not disconnect if the vent handler is throwing an exception.

I will work on the disconnection logic in the next weeks - it would be fine to have some observation on how it should work.

@chelliwell
Copy link
Contributor Author

I've modified my client lib/app to use this library, and taken a look at various connection situations. My top-level app is able to catch: the server being offline; the server rejecting the websocket connection; and subscription errors such as mismatch between client classes and the server schema.
What I haven't been able to fully hook into is if the server goes offline after the subscription has been made.
My lib has a simple 'subscribe' function that does all the work on your library, and just returns the Task<IGraphQLSubscriptionOperation> to the top-level app (or null/throw if socket/sub errors). My lib hooks the GraphQLSubscriptionClient.Disconnected event and this fires if the server goes down. I'm not sure how this can inform the top-level app of the disconnect though - perhaps I just need to implement a 'disconnect' callback mechanism in my two parts?
Anyway, I'm not sure about how much to attack my stuff if you might be thinking of extra/different 'coping mechanisms' lower down, that's my observations so far.

@sahb1239 sahb1239 modified the milestones: 2.2.0, 3.0.0 Jan 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants