Reputation: 18790
I have tried several different SSE-plugins to receive server-sent events in a Flutter Web app, and all of them can connect but I don't receive any events in Flutter. However, if I open DevTools in Chrome and go to Network -> EventStream, I see the events coming in from the server. What could be the reason I don't receive them in the app?
I have tried sse, sse_client and eventsource, but the result is the same in all of them.
Here's how I implemented the app using the sse_client plugin:
sseClient = SseClient.connect(Uri.parse('https://example.com/test-sse/index.php'));
print('sse connected');
sseClient.stream.listen(
(event) {
print('sse event: ${event.toString()}');
},
onError: (err){
print('sse error');
},
onDone: (){
print('sse closed');
},
);
The only output I get is sse connected
, and then nothing - even though the events keep coming in the DevTools Network/EventStream tab.
Here's my PHP test script:
<?php
ob_end_clean();
set_time_limit(60);
while (true) {
// Headers must be processed line by line.
header('Access-Control-Allow-Origin: http://localhost:56008');
header('Access-Control-Allow-Credentials: true');
header('Content-Type: text/event-stream; charset=utf-8');
header('Cache-Control: no-cache');
$data = [
'message' => 'Event: server-time='.date('G:H:s', time()),
'dummy' => str_repeat(' ',1024*64)
];
print("id: ".microtime()."\n");
print("event: ping\n");
print('data: '.json_encode($data)."\n");
print("\n");
ob_flush();
flush();
sleep(1);
}
I have tried removing the id
and the dummy
etc., but the result is the same - the browser receives the events, but the app doesn't receive anything.
Upvotes: 4
Views: 5663
Reputation: 2051
Use fetch_client
at web until this open Flutter issue is resolved.
sse_stream.dart
: Get stream on Android/iOS/Mac/Windows:
import 'package:http/http.dart';
Future<ByteStream> getStream(Request request) async {
final client = Client();
StreamedResponse response = await client.send(request);
return response.stream;
}
sse_stream_web.dart
: Get stream on web:
import 'package:fetch_client/fetch_client.dart';
import 'package:http/http.dart';
Future<ByteStream> getStream(Request request) async {
final FetchClient fetchClient = FetchClient(mode: RequestMode.cors);
final FetchResponse response = await fetchClient.send(request);
return response.stream;
}
Conditional import:
import 'path/to/sse_stream.dart' if (dart.library.js) 'path/to/sse_client_web.dart';
Upvotes: 4