-
Notifications
You must be signed in to change notification settings - Fork 87
Support reconnects on page refreshes for SSE client connections #2727
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
Conversation
If we treat reloads as parts of an app lifecycle, it seems natural to preserve an app instance id on full reloads, and looks like a session storage is a good fit. Fixes dart-lang#2726.
a6ab635 to
8fd89a7
Compare
jyameo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me and addresses the breakpoint flakiness. My main concern is ensuring this doesn't regress multi-browser support or standard stability. Please manually verify that page refreshes, hot restarts, and hot reloads all continue to work as expected. In particular, make sure we can open the app in multiple browsers simultaneously and perform hot reloads on all of them without any interference or connection collisions. Since we lack automated tests for the multi-browser scenario, this manual validation is essential.
Thanks @iinozemtsev
|
Thanks @jyameo! I did an excessive internal testing, but I don't have much experience with using fully open-source webdev. I'll try to follow https://github.com/dart-lang/webdev/blob/main/example/README.md tomorrow, but if you have some other app I can try or any other instructions, please let me know. |
|
This generally LGTM (nice use of
I think those instructions are pretty outdated and I don't know if they still work. I'd try it with Flutter where Flutter tools' pubspec points to your local |
|
It took me a while to figure out how to use flutter tools with local webdev changes, but eventually I succeeded (but unfortunately I left all local changes on my office laptop, so not citing it here). I found out that e2d14f1 breaks Instead I went down the rabbit hole trying to understand why I can't reproduce #2726 with an external stack. Turned out that the client -> dwds connection protocol is controlled by a flag and is independent from whether dwds uses chrome proxy service or websocket proxy service:
So there were two important differences:
When I tried an internal stack over localhost via chrome remote desktop, it could also reconnect successfully as is, because the SSE connection was instantly switching to keepAliveMode. I tried enabling websockets internally, and so far it seems to work, but I didn't test how persistent the connection is (e.g. what happens if you leave the debugger unattended for lunch) and it still requires a smaller change to client.dart, I'll send a separate PR for it: @@ -323,6 +324,10 @@ String _fixProtocol(String url) {
uri.scheme == 'ws' &&
uri.host != 'localhost') {
uri = uri.replace(scheme: 'wss');
+ } else if (window.location.protocol == 'https:' &&
+ uri.scheme == 'ws' &&
+ uri.host != 'localhost') {
+ uri = uri.replace(scheme: 'wss');
}
return uri.toString();
}I think it still makes sense to land this change, but it also makes sense to try switching the internal stack to websockets. |
|
Update: yeah, while I've been writing the above comment, the websocket connection got terminated by a timeout after 4 minutes Upd: leaving the setup mid-debug (paused on a breakpoint) for 4+ minutes and ten trying to restart from an ide just crashes the whole DDR :) What do you think about sending empty heartbeat messages from the client by a timer? |
|
last update for today: looks like neither server, nor client heartbeats go through when the app is paused in the debugger and left unattended, so I think the internal setup should stick to SSE. It also means that this change is unlikely to affect other stacks, which use websockets: for websocket proxy service this change is a mere refactor, it changes only sse logic. We can make it even "less affecting" by scoping the client.dart change (ids from session storage) only for SSE connections, but that's probably too defensive. |
Thanks for bringing this up. I have a fix for this: flutter/flutter#180108
Having consistent code everywhere sounds great, but per your investigation, it looks like that's not tractable in the near-term so this is fine especially since that's the current state.
I have a feeling this would complicate the code (both in client.dart and elsewhere) so I agree. |
If we treat reloads as parts of an app lifecycle, it seems natural to preserve an app instance id on full reloads, and looks like a session storage is a good fit.
Fixes #2726.
Contribution guidelines:
dart format.Many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.
Note: The Dart team is trialing Gemini Code Assist. Don't take its comments as final Dart team feedback. Use the suggestions if they're helpful; otherwise, wait for a human reviewer.