【问题标题】:How to make websocket stream broadcast to many other pages?如何使 websocket 流广播到许多其他页面?
【发布时间】:2018-11-02 02:24:09
【问题描述】:

我正在监听一个 websocket 流:

widget.channel.stream.listen((data) {
  print("!!!!new msg: $data");
  var dataJson = json.decode(data);
  print(dataJson["content"]);
  // do my job
  setState(() {
    _allAnimateMessages.insert(0, newMsg);
  });
  newMsg.animationController.forward();
});

但是,当再次进入该页面时,出现错误: Bad state: Stream has already been listened to.

如何使它成为广播,其他页面可以接收该广播?

【问题讨论】:

  • 您能否提供更多提示您正在使用什么: - 什么库/包 - 什么是channel? - 这段代码在您的应用程序中的什么位置?

标签: websocket stream dart flutter


【解决方案1】:

由于没有有用的答案,我在这里更新我的答案以供其他参考。

  1. 重复订阅流是 Flutter 中的一种期望行为。

如果您只是使用 StreamBuilder,则该流只能监听一次。想一想,如果您的流可以监听许多其他页面或小部件,那么数据将被重复。

  1. 但如果您想使用一个流,并更新所有小部件

在开发复杂的应用程序时确实会发生这种情况,例如,您正在构建一个聊天应用程序,新消息来了,您应该更新许多页面 UI(您的对话聊​​天 ui,您的会话列表 ui....) ,那么你应该在很多页面中订阅这个流,我仍然没有找到合适的方法来做到这一点,除了让这个流被广播,然后做你的工作。

【讨论】:

    【解决方案2】:

    您可以使用广播。

     //Here is the solution
     StreamController<String> streamController = new StreamController.broadcast();   //Add .broadcast here
    
    //Now you can listen from various places
    @override
    void initState() {
      super.initState();
    
      print("Creating a StreamController...");
      //First subscription
      streamController.stream.listen((data) {
        print("DataReceived1: " + data);
      }, onDone: () {
        print("Task Done1");
      }, onError: (error) {
        print("Some Error1");
      });
      //Second subscription
      streamController.stream.listen((data) {
        print("DataReceived2: " + data);
      }, onDone: () {
        print("Task Done2");
      }, onError: (error) {
        print("Some Error2");
      });
    
      streamController.add("This a test data");
      print("code controller is here");
    
    }
    

    字体:https://medium.com/@ayushpguptaapg/using-streams-in-flutter-62fed41662e4

    使用广播时,您可以在同一个流中拥有多个侦听器。

    如果你只是使用没有“.broadcast()”的流,你只能有一个监听器

    【讨论】:

    • 添加消息必须调用streamController.add(),那么如何在另一个类或页面上获取streamController的引用对象呢?
    【解决方案3】:

    解决方案web_socket_channel:

    final channel = IOWebSocketChannel.connect(socketUrl);
    final streamController = StreamController.broadcast();
    streamController.addStream(channel.stream);
    

    之后只需使用streamController.stream 来监听网络套接字事件。

    【讨论】:

      猜你喜欢
      • 2021-01-19
      • 1970-01-01
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 2012-08-23
      • 2017-10-13
      • 1970-01-01
      相关资源
      最近更新 更多