Flutter创建每秒返回bool的Stream 实现每分钟检测服务器状态
每秒返回bool值的Stream实现
直接使用Dart内置的Stream.periodic构造器即可快速实现周期发射值的流,你可以在回调中自定义bool值的生成逻辑,参考代码:
/// 每秒返回一个bool值的Stream Stream<bool> oneSecondBoolStream() { return Stream.periodic( const Duration(seconds: 1), (tickCount) { // 替换为你实际的业务判断逻辑,示例为偶数秒返回true、奇数秒返回false return tickCount.isEven; }, ); }
使用注意:
- 持有流的
StreamSubscription实例,在不需要使用(比如页面销毁)时调用cancel()方法取消订阅,避免内存泄漏 - 如果需要多个位置同时订阅该流,调用
asBroadcastStream()将其转为广播流即可
每分钟检测服务器状态的场景适配与实现
Stream完全适用于定时轮询服务器状态的场景:相比手动维护Timer定时器,Stream自带状态推送能力,可以直接和Flutter的StreamBuilder配合构建响应式UI,同时天然支持订阅生命周期管理、错误捕获、多订阅者分发,代码维护成本更低。
具体实现代码如下:
首先定义服务器状态实体,承载需要反馈给用户的信息:
/// 服务器状态模型 class ServerStatus { /// 服务是否可用 final bool isAvailable; /// 给用户展示的提示信息 final String statusMsg; /// 接口响应耗时 final int responseCostMs; const ServerStatus({ required this.isAvailable, required this.statusMsg, required this.responseCostMs, }); }
编写服务器状态检测流:
/// 每分钟轮询一次服务器状态的Stream Stream<ServerStatus> serverStatusPollStream() { return Stream.periodic( const Duration(minutes: 1), (_) async { final stopwatch = Stopwatch()..start(); try { // 替换为你实际的服务器健康检测接口请求逻辑 // final resp = await http.get(Uri.parse('你的服务健康检查地址')); // 模拟接口请求 await Future.delayed(const Duration(milliseconds: 150)); stopwatch.stop(); return ServerStatus( isAvailable: true, statusMsg: "服务器运行正常", responseCostMs: stopwatch.elapsedMilliseconds, ); } catch (err) { stopwatch.stop(); return ServerStatus( isAvailable: false, statusMsg: "服务器连接异常,请稍后重试", responseCostMs: stopwatch.elapsedMilliseconds, ); } }, ).asyncMap((futureRes) => futureRes); // 处理异步回调结果 }
在页面中使用的示例:
class ServerStatusBar extends StatefulWidget { const ServerStatusBar({super.key}); @override State<ServerStatusBar> createState() => _ServerStatusBarState(); } class _ServerStatusBarState extends State<ServerStatusBar> { late final Stream<ServerStatus> _statusStream; StreamSubscription<ServerStatus>? _subscription; @override void initState() { super.initState(); _statusStream = serverStatusPollStream(); // 进入页面立刻触发一次检测,无需等待1分钟才展示首次结果 _statusStream.first; _subscription = _statusStream.listen((status) { // 可在这里处理状态变化的额外逻辑,比如异常时弹出提示、上报日志等 }); } @override Widget build(BuildContext context) { return StreamBuilder<ServerStatus>( stream: _statusStream, builder: (context, snapshot) { if (!snapshot.hasData) { return const Text("正在检测服务器状态..."); } final status = snapshot.data!; return Row( mainAxisSize: MainAxisSize.min, children: [ Icon( status.isAvailable ? Icons.check_circle : Icons.error_outline, color: status.isAvailable ? Colors.green : Colors.red, size: 18, ), const SizedBox(width: 6), Text("${status.statusMsg} 响应耗时${status.responseCostMs}ms"), ], ); }, ); } @override void dispose() { _subscription?.cancel(); super.dispose(); } }
额外优化建议:
- 可以给流增加并发锁逻辑,避免上一次接口请求未完成时就发起下一次轮询,造成请求堆积
- 如果需要全局共享服务器状态,将流转为广播流后放入全局状态管理中即可,所有订阅者都会同步收到最新状态
- 应用切后台时可以调用订阅实例的
pause()方法暂停轮询,回到前台调用resume()恢复,减少不必要的资源消耗
内容的提问来源于stack exchange,提问作者sanithu jayakody
相关产品推荐
相关产品推荐

