Flutter如何实现SSE(Server-Sent Events)客户端

在Flutter中如何实现SSE(Server-Sent Events)客户端?我尝试用dart:io的HttpClient,但连接建立后无法持续接收服务器推送的事件。有没有成熟的package推荐?或者需要自己实现EventSource协议?处理重连、消息解析和错误处理时有哪些注意事项?

2 回复

使用httpstream_channel库。创建http.Client,发送GET请求,设置Accept: text/event-stream。监听响应流,解析事件数据。处理连接、重连和错误。

更多关于Flutter如何实现SSE(Server-Sent Events)客户端的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现SSE客户端,可以通过http包配合Stream来实现。以下是具体实现步骤:

1. 添加依赖

pubspec.yaml中添加:

dependencies:
  http: ^0.13.0

2. 核心实现代码

import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

class SSEClient {
  static Stream<String> subscribeToSSE(String url) async* {
    final client = http.Client();
    final request = http.Request('GET', Uri.parse(url));
    final response = await client.send(request);

    // 使用StreamController处理数据流
    final stream = response.stream
        .transform(utf8.decoder)
        .transform(const LineSplitter());

    try {
      await for (final line in stream) {
        if (line.startsWith('data:')) {
          final data = line.substring(5).trim();
          if (data.isNotEmpty) {
            yield data;
          }
        }
      }
    } finally {
      client.close(); // 确保关闭连接
    }
  }
}

3. 使用示例

class ExamplePage extends StatefulWidget {
  @override
  _ExamplePageState createState() => _ExamplePageState();
}

class _ExamplePageState extends State<ExamplePage> {
  StreamSubscription? _subscription;
  String _message = '';

  @override
  void initState() {
    super.initState();
    _startListening();
  }

  void _startListening() {
    _subscription = SSEClient.subscribeToSSE('http://your-server.com/events')
        .listen((data) {
      setState(() {
        _message = data;
      });
    }, onError: (error) {
      print('SSE Error: $error');
    });
  }

  @override
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Received: $_message'),
      ),
    );
  }
}

关键点说明:

  1. 使用http.Client().send()获取流式响应
  2. 通过transform进行UTF-8解码和行分割
  3. 过滤以data:开头的行并提取有效数据
  4. 使用async*yield返回数据流
  5. 务必在dispose时取消订阅和关闭连接

注意事项:

  • 服务端需要正确设置CORS
  • 支持自动重连机制可增加重试逻辑
  • 生产环境建议添加错误处理和心跳检测

这样即可在Flutter中实现基本的SSE客户端功能。

回到顶部