【问题标题】:Flutter - Stream has already been listened to using socketsFlutter - 已经使用套接字监听了流
【发布时间】:2020-02-18 20:58:12
【问题描述】:

我有点迷茫,我使用Streambuilder()函数获取了我的Esp8266的数据,问题是,每次我换屏并弹回屏幕时,我都会收到错误消息:Stream已经被监听了到

我读到我应该在广播中使用Streamcontroller。但是我不知道如何订阅,或者监听我的套接字的变化。

现在结果是我的Text 小部件中没有任何内容。

这是我的代码(只有一页的简化版)

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'dart:io';
import 'dart:async';

void main() async{
  Socket sock = await Socket.connect('192.168.1.24', 80);
runApp(MyApp(sock));
}

class MyApp extends StatelessWidget {
  Socket socket;

  MyApp(Socket s){
    this.socket = s;
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page',
        channel : socket,
      ),

    );
  }
}

class MyHomePage extends StatefulWidget {
  final Socket channel;
  MyHomePage({Key key, this.title, this.channel}) : super(key: key);



  final String title;



  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = TextEditingController();

  StreamController streamController = new StreamController.broadcast();   
//I have my controller here, but I need it to listen to my widget.channel




  void _togglePower(){
    widget.channel.write("Apero\n");

  }
  /*
  @override
  void dispose(){
    widget.channel.close(); //Faire un flush avant de close.
    super.dispose();
  }*/

  @override
  void dispose(){
    streamController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {


    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(

        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              child: Text("Testou",
              style: TextStyle(
                color: Colors.amber,
                fontStyle: FontStyle.italic,
                fontSize: 20
              )
            ),
        color: Colors.black,
              onPressed: _togglePower,
            ),


            Form(
              child: TextFormField(
                controller: _controller,
                decoration: InputDecoration(labelText: 'Send a message'),
              ),
            ),
            StreamBuilder(
              stream: streamController.stream,
              builder: (context, snapshot) {
                return Padding(
                  padding: const EdgeInsets.symmetric(vertical: 24.0),
                  child: Text(snapshot.hasData
                      ? '${String.fromCharCodes(snapshot.data)}'
                      : 'loading'),
                );
              },
            )
          ],
        ),
      ),

    );
  }

}

或者有没有办法让它更简单,使用 widget.channel.listen ?

感谢您的帮助! 祝你晚上愉快:)

【问题讨论】:

    标签: sockets flutter stream


    【解决方案1】:

    当您在单个订阅流上多次调用 listen() 时会显示此错误。 我在源代码中找到以下几行。

    • 不允许在单一订阅流上收听两次
    • 即使在第一次订阅被取消后

    所以你需要把你的socket改成BroadcastSteam,在这里保存一个实例,不要多次调用asBroadcastStream()。

    静态 bcSteam = socket.asBroadcastStream();

    bcSteam.listen((event) {
      final data = json.decode(utf8.decode(event));
      handleSocketData(data);
    });
    

    【讨论】:

      猜你喜欢
      • 2023-02-16
      • 2018-11-12
      • 2011-02-15
      • 2018-07-13
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 2023-01-31
      • 1970-01-01
      相关资源
      最近更新 更多