flutter - Flutter Web - http StreamedResponse 作为客户端接收 SSE
问题描述
有一个 Flutter 应用程序,能够在移动设备上运行时接收 SSE 文本/事件流事件,但在 chrome 网络上运行时接收不到相同的 SSE 文本/事件流事件。
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();
}
}
在服务器端,我可以看到 Flutter 应用程序始终可以正常订阅,因为我可以看到 Sink 正在添加。并且服务器端总是将事件分派给 Sink,但 Flutter 应用程序仅在作为移动应用程序运行时接收事件,而不是在作为 Chrome 网络应用程序运行时接收事件。
是否有一个原因?这不是在浏览器和移动应用程序上运行的客户端颤振应用程序上接收 SSE 事件的正确方法吗?
Flutter 版本为 1.10.6。Dart 版本是 2.5.1
- - 更新 - -
进行了颤振升级,现在运行以下内容:
Flutter 1.10.15-pre.79 • channel master • https://github.com/flutter/flutter.git
Framework • revision 72d5c1c805 (2 hours ago) • 2019-10-11 03:58:43 -0400
Engine • revision 8dabfb90a1
Tools • Dart 2.6.0 (build 2.6.0-dev.7.0 965b8cb1d8)
但仍然遇到相同的行为,即在作为移动应用程序运行时可以接收流式事件,但在作为 Chrome 网络应用程序运行时无法接收到流式事件。
--- 更新 2 ---
我一直在阅读,在 Web 浏览器上运行时可能存在与 CORS 相关的问题,但据我所知,CORS 没有问题。服务器端的 CORS 已配置为接受所有来源(即"*"
),配置为接受"GET"
和"OPTIONS"
方法,并配置为接受所有标头(即"*"
)。
在 Chrome 浏览器中调试显示返回的响应是 200,并且可以看到以下响应标头:
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
不幸的是,我对 http 协议知之甚少,所以我不知道上面的任何响应标头是否应该引起关注为什么无法在 Web 浏览器上接收事件流?
附带说明一下,flutter/dart 代码最初是作为 angulardart/dart 代码编写的,并且该代码在 Chrome Web 浏览器上运行时能够很好地接收流式事件(因此假设 CORS 配置正确)。
任何有关此问题的帮助或指示将不胜感激。在 Chrome 上当前版本的 Flutter Web 中,即使是简单的“是”接收流式事件也是可能的,因此您必须在服务器端做错了什么。或者“否”这在 Chrome 上当前版本的 Flutter Web 中不起作用,但最终它将/永远不会,等等。
解决方案
推荐阅读
- reactjs - 当我尝试运行 React Native Scan QR Code 示例时出现错误
- emacs - 无法打开安装了撤消树的新框架
- jquery - 显示来自日期属性的文本和带有参数的 URL 链接
- java - 如何使输出为“鳄梨卷、鲑鱼手卷、加州卷、味噌汤”等。我不知道如何正确使用 subtring 方法
- javascript - 当 Electron 中最后一次修改日期更改时,如何将锚标记的颜色更改为下载的文件?
- java - 在可用的应用程序模块中找不到运行“java”的模块
- apache-beam - Apache Beam TextIO 不适用于 Spark Runner
- maven - 如何使用 pom.xml 创建两个具有不同类的 jar 文件?
- javascript - $window.focus() 不适用于 iOS Safari 中的现有选项卡
- vue.js - Vuex:即使未提交/分派,为什么状态中的数组也会发生变异(可能通过计算属性)