如何在Flutter中使用Dio包监听服务器发送事件(SSE)流
Flutter 用Dio实现SSE流订阅的正确方案
现有代码的问题
- 未指定
responseType: ResponseType.stream,Dio默认会全量接收响应后再返回,无法拿到实时流式数据 - 错误将请求Future转为流监听,而非监听响应内部的数据流,无法获取SSE持续推送的内容
- Accept头设置为
*/*不符合SSE规范,部分服务端会因此返回404或拒绝响应 - 未显式指定请求方法,也未校验url是否和可运行的http版本完全一致,是404错误的常见诱因
正确实现代码
import 'package:dio/dio.dart'; import 'dart:convert'; void subscribeSSE() async { print("Subscribing.."); try { final dio = Dio(); // 此处url必须和你之前http版本的请求地址完全一致,避免404 const String sseUrl = "http://192.168.1.11:8080/myserver/events"; final Response response = await dio.get( sseUrl, options: Options( headers: { "Cache-Control": "no-cache", "Accept": "text/event-stream", // 如有认证、跨域相关头要求,补充在此处 }, // 核心配置:指定响应类型为流,才能拿到SSE的实时数据块 responseType: ResponseType.stream, ), ); print("Subscribed!"); print("响应状态码:${response.statusCode}"); // 监听流式响应的数据推送 response.data.stream.listen( (Uint8List data) { // 解码二进制数据为可读字符串 final String content = utf8.decode(data); print("收到SSE数据:$content"); }, onError: (error) { print("SSE流出错:$error"); }, onDone: () { print("SSE连接已关闭"); }, ); } catch(e) { print("请求捕获异常:$e"); } }
额外注意事项
- 先排查404问题:复制http版本的请求地址直接赋值给Dio的请求url,确认路径、端口、IP、查询参数无任何差异
- 如果服务端开启了请求校验,要保证Dio请求的所有头信息和http版本完全一致
- 生产环境使用时建议配置Dio的超时时间,避免长时间无数据时连接被系统回收
内容的提问来源于stack exchange,提问作者Ritesh Singh
相关产品推荐
相关产品推荐

