Open shyndman opened 3 years ago
We had a similar issue with the nhost-js-sdk.
This was our solution there:
https://github.com/nhost/nhost-js-sdk/blob/master/src/Auth.ts#L639-L650
Yes! I saw that while porting, and do have questions about that (since people are now building for Flutter Web.)
But in this case, it's not exactly the same issue.
What I'm seeing is Android suspending all network activity while "dozing" (a state that is entered after a few minutes of the screen being off). In this state, application code continues to run, which includes timer callbacks (possibly at a reduced or less exact rate), but network requests never go out (so JWTs don't refresh), and websocket keep alives never come in (leading to socket disconnects+reconnection attempts).
When everything wakes back up, it's in a bad state, because you have a websocket queued up to send its initial payload (which will contain the "current", stale, JWT), and a JWT refresh queued up that whose response won't be received before that payload is sent.
It actually also occured on iOS
Ah, well I believe it's even simpler in that case.
iOS standby mode is a lot like Doze from what I've read, but is even stricter. I should be able to repro the issues I've seen there with the same testbed.
Thank you for letting me know.
@MaxSchilling has reported that his graphql client is making a request using a stale JWT after the Android device has been off for some amount of time.
After some research, I suspect that Android Doze suspending timers and network connections. When the app resumes, the websocket notices and begins reconnecting with the old JWT, which happens concurrently with the JWT refresh.
I'm confirming now. If correct, the solution is simple, because the way
gql_websocket_link
is configured gives us control over socket creation, and that API is async — we can keep it waiting for a JWT refresh.