首页 > 解决方案 > 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 中不起作用,但最终它将/永远不会,等等。

标签: flutterdart

解决方案


推荐阅读