Have a Flutter App that is able to receive SSE text/event-stream events when running on mobile but it is not receiving the same SSE text/event-stream events when running on the chrome web.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
http.Client _client;
MyApp() : super() {
print("Ctor called");
subscribe();
}
@override
Widget build(BuildContext context) {
print("building..");
return MaterialApp(
title: 'Flutter SSE',
home: Scaffold(
appBar: AppBar(
title: Text('Receive SSE Events'),
),
body: Center(
child: Text('Ready for events..'),
),
),
);
}
subscribe() async {
print("Subscribing..");
try {
_client = http.Client();
var request = new http.Request("GET", Uri.parse("http://192.168.1.11:8080/myserver/events"));
request.headers["Cache-Control"] = "no-cache";
request.headers["Accept"] = "text/event-stream";
Future<http.StreamedResponse> response = _client.send(request);
print("Subscribed!");
response.asStream().listen((streamedResponse) {
print("Received streamedResponse.statusCode:${streamedResponse.statusCode}");
streamedResponse.stream.listen((data) {
print("Received data:$data");
});
});
} catch(e) {
print("Caught $e");
}
}
unsubscribe() {
_client.close();
}
}
On the server-side, I can see that the flutter app always subscribes okay as I can see the Sink being added. And the server-side always dispatches the events to the Sink but the flutter app only receives the events when running as a mobile app and NOT when running as a Chrome web app.
C:\Users\pondeMuse\flutter\bin\flutter.bat doctor --verbose
[√] Flutter (Channel master, v1.10.15-pre.188, on Microsoft Windows [Version 10.0.16299.1087], locale en-GB)
• Flutter version 1.10.15-pre.188 at C:\Users\pondeMuse\flutter
• Framework revision 584ee10c68 (2 days ago), 2019-10-21 07:49:28 -0700
• Engine revision 8aefcd8575
• Dart version 2.6.0 (build 2.6.0-dev.8.0 a61c775db8)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at C:\Users\pondeMuse\AppData\Local\Android\sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 29.0.2
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
[√] Android Studio (version 3.5)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 40.2.2
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
[!] IntelliJ IDEA Community Edition (version 2019.2)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.2.5
X Flutter plugin not installed; this adds Flutter specific functionality.
• Dart plugin version 192.7402
• For information about installing plugins, see
https://flutter.dev/intellij-setup/#installing-the-plugins
[√] Connected device (2 available)
• Chrome • chrome • web-javascript • Google Chrome 77.0.3865.120
• Web Server • web-server • web-javascript • Flutter Tools
! Doctor found issues in 1 category.
I keep reading that there could be issues associated with CORS when running on a web browser but as far as I can see, there are no issues with CORS. CORS on the server-side has been configured to accept all origins (i.e. "*"), configured to accept "GET" and "OPTIONS" methods, and configured to accept all headers (i.e. "*").
Debugging in Chrome browser shows that the response back is a 200 and can see the following response headers:
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/event-stream;charset=UTF-8
Expires: 0
Pragma: no-cache
transfer-encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
Unfortunately, I don't know enough about the http protocol so I don't know if any of the response headers above should be reason for concern as to why an event stream cannot be received on a web browser?
As a side note, the flutter/dart code was originally written as angulardart/dart code and that code was able to receive streamed events fine when running on Chrome web browser (Therefore assuing that CORS was configured correctly).
Any help or pointers on this issue would be greatly appreciated. Even a simple "Yes" receiving streamed events is possible in current version of flutter web on Chrome so you must be doing something wrong on the server side. Or "No" this does not work in current version of flutter web on Chrome but eventually it will/never will, etc.
Hi @ponderMuse,
Did you find a solution ? I have succeeded on SSE with Flutter - Android. But I am stuck like you with the Web version.
All help is welcome !
Thanks
Hello @sebastienharinck ,
I've only just read your post. Please see the comments from my other post: Not Able to Receive SSE Events.
Basically, at the time of that post, receiving SSE events was possible in a Flutter Web app using package:sse
What package are you using?
Hello @ponderMuse,
Thanks for the link !
I tried package:sse and package:eventsource. I am able to build an app that works on mobile OR web browser. But never both with the same code..
Note : I am pretty new in flutter and dart so maybe I did something wrong. At that moment, are you able to build a flutter app that works for mobile and web browser ? If yes, which package do you use ? And do you still need a conditional imports as your previous post mentions ?
Thanks a lot
I ended up writing my own to work on web and vm, package:sse_client. It by no means complete but it may provide a path to accomplish what your looking for.
I took a look at @jamiewest package, pretty simple implementation, perhaps it's worth having something alike within the http flutter package.
@jamiewest @tomasdev Used package:sse_client but the client gets only the 1st server request not henceforth. Can you please share an example of the implementation? Thanks.
@jamiewest Yes, an example to use the package would be lovely. And what do you do in cases of having an httpOnly cookie? IIUC, The [BrowserClient] that received the httpOnly cookie should be the same client used to request for an SSE connection.