【问题标题】:Bad state: Stream has already been listened to when using IOWebSocketChannel错误状态:使用 IOWebSocketChannel 时已监听 Stream
【发布时间】:2021-03-30 01:49:27
【问题描述】:

我有一个 StreamBuilder,它监听使用包 web_socket_channel: ^1.1.0 创建的流。

Stream getLocationsStream({LatLngBounds latLngBounds, LatLng location}) {
  if (branchMapChannel == null)
    branchMapChannel = IOWebSocketChannel.connect(wsEndpointURL("business/branch/maps"));
  return branchMapChannel.stream;
}

StreamBuilder 监听这个流(getLocationsStream())。我在名为 Maps() 的自定义小部件中使用此 Streambuilder。在主页中调用 Maps() 时,它可以正常工作。但是当 Maps() 在另一个页面上被调用时,它会显示以下错误。

错误状态:Stream 已被监听。

当异常被抛出时,这是堆栈: 我/颤振(2977):#3 _CompleterStream.listen 包:async/src/stream_completer.dart:135 我/颤振(2977):#7 _StreamBuilderBaseState._subscribe 包:flutter/…/widgets/async.dart:137 我/颤振(2977):#8 _StreamBuilderBaseState.initState 包:flutter/…/widgets/async.dart:111 我/颤振(2977):#9 StatefulElement._firstBuild 包:flutter/…/widgets/framework.dart:4812 我/颤振(2977):#10 ComponentElement.mount 包:flutter/…/widgets/framework.dart:4649 我/颤振(2977):#11 Element.inflateWidget 包:flutter/…/widgets/framework.dart:3615 我/颤振(2977):#12 Element.updateChild 包:flutter/…/widgets/framework.dart:3377 我/颤振(2977):#13 ComponentElement.performRebuild 包:flutter/…/widgets/framework.dart:4700

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    出现问题是因为您尝试订阅 Single Subscription Stream 两次。

    如果你查看IOWebSocketChannel的文档,你可以看到:

    流 → 流
    从另一个端点发出值的单订阅流。
    最终

    建议 #1:

    而不是直接将套接字流分配给流生成器:

    • 创建一个 Socket Utility 类(一个 Singleton 或使用依赖注入来传递对象)
    • 在 Socket Utility 类中监听套接字事件
    • 在您的 Socket Utility 中提供添加侦听器的选项
    • 每当流发生变化时,通知所有监听器
    • 在您的 Maps 类中使用 Socket Utility 对象并设置侦听器/回调

    建议 #2:

    只需使用asBroadcastStream 将您的流转换为广播流。

    Stream getLocationsStream({LatLngBounds latLngBounds, LatLng location}) {
      if (branchMapChannel == null) {
        branchMapChannel = IOWebSocketChannel.connect(wsEndpointURL("business/branch/maps"));
        broadCastStream = branchMapChannel.stream.asBroadcastStream();
      }
      return broadCastStream;
    }
    

    【讨论】:

    • @ChristopherMoore 是的,正在寻找文档。我总是喜欢第一种方式,所以先写了,然后添加 asBroadCastStream 作为第二个选项;)
    • 你能分享第一个选项的代码吗?第二个选项不起作用
    • @AbhijithK 您是将流存储在变量中还是只是将其返回:return branchMapChannel.stream.asBroadcastStream();?对于第一个,我已经提到了那里的步骤,如果您需要代码,我必须为您编写一个完整的类。
    • 我尝试将其作为广播流返回,但错误仍然存​​在。让我试试第一个选项。
    • 不,我的意思是如果你像这样返回它:return branchMapChannel.stream.asBroadcastStream(); 错误就会出现。您必须将branchMapChannel.stream.asBroadcastStream(); 的值存储在一个变量中并返回该变量。如我的回答所示,broadCastStream 是一个与 branchMapChannel 范围相同的变量
    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 2020-03-08
    • 2021-03-06
    • 2021-02-03
    • 1970-01-01
    • 2020-04-25
    • 2021-07-04
    • 2021-12-26
    相关资源
    最近更新 更多