Flutter 如何在颤振中向streambuilder发送错误?

Flutter 如何在颤振中向streambuilder发送错误?,flutter,go,grpc,Flutter,Go,Grpc,我正在编写一个聊天应用程序,使用gRPC协议和一个go服务器和一个Flatter客户端。我编写了一个聊天服务,它可以与服务器通信,并在新客户端连接时创建新连接,如果他们愿意,还可以创建新的聊天室。我正在尝试检查客户端想要的聊天室号码是否已经在使用中,然后Flatter客户端应该向用户显示一个错误。如果聊天室号码已经存在,我已经编写了在服务器中返回gRPC错误的代码。我使用streambuilder在屏幕上呈现消息,生成器函数从服务器生成消息 我无法理解如何将chat_service.dart中的

我正在编写一个聊天应用程序,使用gRPC协议和一个go服务器和一个Flatter客户端。我编写了一个聊天服务,它可以与服务器通信,并在新客户端连接时创建新连接,如果他们愿意,还可以创建新的聊天室。我正在尝试检查客户端想要的聊天室号码是否已经在使用中,然后Flatter客户端应该向用户显示一个错误。如果聊天室号码已经存在,我已经编写了在服务器中返回gRPC错误的代码。我使用streambuilder在屏幕上呈现消息,生成器函数从服务器生成消息

我无法理解如何将chat_service.dart中的receiveMessage方法中的错误发送到message_page.dart中的streambuilder,以便使用snapshot.hasError块呈现AlertDialog

服务器。转到

func (s *Server) CreateStream(pcon *chatpb.Connect, stream chatpb.Broadcast_CreateStreamServer) error {
    grpcLog.Infoln("CreateStream called")
    conn := &Connection{
        stream: stream,
        id:     pcon.User.Id,
        active: true,
        error:  make(chan error),
    }
    chatroom := pcon.User.GetChatRoomNo()

    if pcon.WantsNewRoom {
        if _, ok := s.Connections[chatroom]; !ok {
            newConnection := []*Connection{conn}
            s.Connections[chatroom] = newConnection
            grpcLog.Infoln("New chatroom created")
        } else {
            grpcLog.Infoln("Chatroom already exists")
            return status.Errorf(
                codes.AlreadyExists,
                fmt.Sprintf("The Chatroom already exists"),
            )
        }
    } else {
        if _, ok := s.Connections[chatroom]; ok {
            s.Connections[chatroom] = append(s.Connections[chatroom], conn)
            grpcLog.Infoln("New user added to chatroom - ", chatroom)
        } else {
            grpcLog.Infoln("Chatroom does not exists")
            return status.Errorf(
                codes.NotFound,
                fmt.Sprintf("The Chatroom does not exist"),
            )
        }
    }

    // if _, ok := s.Connections[chatroom]; ok {
    //  s.Connections[chatroom] = append(s.Connections[chatroom], conn)
    // } else {
    //  newConnection := []*Connection{conn}
    //  s.Connections[chatroom] = newConnection
    // }

    return <-conn.error
}
func(s*Server)CreateStream(pcon*chatpb.Connect,stream chatpb.Broadcast\u CreateStreamServer)错误{
grpcLog.Infoln(“调用CreateStream”)
连接:=&连接{
小溪:小溪,
id:pcon.User.id,
主动:对,
错误:make(chan error),
}
聊天室:=pcon.User.GetChatRoomNo()
如果pcon.wantNewroom{
如果u,ok:=s.Connections[chatroom];!ok{
新连接:=[]*连接{conn}
s、 连接[聊天室]=新建连接
grpcLog.Infoln(“新建聊天室”)
}否则{
Infoln(“聊天室已经存在”)
返回状态。Errorf(
codes.AlreadyExists,
fmt.Sprintf(“聊天室已经存在”),
)
}
}否则{
如果,ok:=s.Connections[聊天室];ok{
s、 连接[聊天室]=附加(s.Connections[聊天室],康涅狄格州)
Infoln(“添加到聊天室的新用户-”,聊天室)
}否则{
grpcLog.Infoln(“聊天室不存在”)
返回状态。Errorf(
代码。未找到,
fmt.Sprintf(“聊天室不存在”),
)
}
}
//如果,ok:=s.Connections[聊天室];ok{
//s.Connections[chatroom]=附加(s.Connections[chatroom],康涅狄格州)
//}其他{
//新连接:=[]*连接{conn}
//s.Connections[聊天室]=新建连接
// }
返回_MessagePageState();
}
类_MessagePageState扩展状态{
@凌驾
void initState(){
super.initState();
控制器=文本编辑控制器();
messages=Set();
scrollController=scrollController();
_ytcontroller=YoutubePlayerController(
initialVideoId:youtubeplyer.convertUrlToId(widget.videoURL),
标志:YoutubePlayerFlags(自动播放:false));
}
设置消息;
文本编辑控制器;
滚动控制器滚动控制器;
YoutubePlayerController\u ytcontroller;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:Text('Chatroom-'+widget.chatroomid.toString()),
),
正文:中(
子:列(
儿童:[
YoutubePlayer(
控制器:_-ytcontroller,
showVideoProgressIndicator:对,
ProgressIndicator颜色:Colors.琥珀色,
ProgressColor:ProgressBarColor(
播放颜色:Colors.amber,handleColor:Colors.amberAccent),
),
灵活的(
孩子:StreamBuilder(
流:widget.service
.ReceiveMessage(WantNewroom:widget.WantNewroom),
生成器:(上下文,快照){
如果(snapshot.hasError){//我想在这里处理这个错误
返回中心(
子:警报对话框(
标题:文本(“错误”),
内容:文本(快照.错误),
行动:[
扁平按钮(
已按下:(){
Navigator.pop(上下文);
},
子项:文本(“确定”))
],
),
);
}
如果(!snapshot.hasData){
返回中心(子项:文本(“键入消息开始”);
}
messages.add(snapshot.data);
返回列表视图(
控制器:滚动控制器,
儿童:信息
.地图(
(msg)=>MessageBubble(
发件人名称:msg.id,
内容:msg.content,
时间戳:msg.timestamp,
isMe:msg.id==widget.service.user.name,
),
)
.toList(),
);
},
),
),
划船(
儿童:[
扩大(
孩子:填充(
填充:LTRB(8.0,8.0,8.0,3.0)中的常量边集,
孩子:TextField(
控制器:控制器,
装饰:输入装饰(
边框:大纲输入边框(
边界半径:
边界半径所有(半径圆形(20.0)),
labelText:“键入消息”),
),
),
),
填充物(
填充:常数边集全部(5.0),
子:浮动操作按钮(
已按下:(){
widget.service.sendMessage(controller.text);
controller.clear();
滚动控制器

  Stream<Message> recieveMessage({bool wantsNewRoom}) async* {
    print("RecieveMsg Called");
    print(user);
    Connect conn = Connect()
      ..user = user
      ..active = true
      ..wantsNewRoom = wantsNewRoom;

    await for (var msg in client.createStream(conn)) { //the error in this line from the server
      print("in the loop");
      yield msg;
    }

  }
}
class MessagePage extends StatefulWidget {
  final ChatService service;
  final Int64 chatroomid;
  final bool wantsNewRoom;
  final String videoURL;
  MessagePage(this.service, this.chatroomid, this.wantsNewRoom, this.videoURL);
  @override
  _MessagePageState createState() => _MessagePageState();
}

class _MessagePageState extends State<MessagePage> {
  @override
  void initState() {
    super.initState();
    controller = TextEditingController();
    messages = Set();
    scrollController = ScrollController();
    _ytcontroller = YoutubePlayerController(
        initialVideoId: YoutubePlayer.convertUrlToId(widget.videoURL),
        flags: YoutubePlayerFlags(autoPlay: false));
  }

  Set<Message> messages;
  TextEditingController controller;
  ScrollController scrollController;
  YoutubePlayerController _ytcontroller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chatroom - ' + widget.chatroomid.toString()),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            YoutubePlayer(
              controller: _ytcontroller,
              showVideoProgressIndicator: true,
              progressIndicatorColor: Colors.amber,
              progressColors: ProgressBarColors(
                  playedColor: Colors.amber, handleColor: Colors.amberAccent),
            ),
            Flexible(
              child: StreamBuilder<Message>(
                stream: widget.service
                    .recieveMessage(wantsNewRoom: widget.wantsNewRoom),
                builder: (context, snapshot) {
                  if (snapshot.hasError) {    //I want to handle the error here
                    return Center(
                      child: AlertDialog(
                        title: Text("Error"),
                        content: Text(snapshot.error),
                        actions: <Widget>[
                          FlatButton(
                              onPressed: () {
                                Navigator.pop(context);
                              },
                              child: Text("OK"))
                        ],
                      ),
                    );
                  }
                  if (!snapshot.hasData) {
                    return Center(child: Text("Start by typing a message"));
                  }
                  messages.add(snapshot.data);
                  return ListView(
                    controller: scrollController,
                    children: messages
                        .map(
                          (msg) => MessageBubble(
                            senderName: msg.id,
                            content: msg.content,
                            timestamp: msg.timestamp,
                            isMe: msg.id == widget.service.user.name,
                          ),
                        )
                        .toList(),
                  );
                },
              ),
            ),
            Row(
              children: <Widget>[
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 3.0),
                    child: TextField(
                      controller: controller,
                      decoration: InputDecoration(
                          border: OutlineInputBorder(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(20.0))),
                          labelText: "Type a message"),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(5.0),
                  child: FloatingActionButton(
                    onPressed: () {
                      widget.service.sendMessage(controller.text);
                      controller.clear();
                      scrollController
                          .jumpTo(scrollController.position.maxScrollExtent);
                    },
                    child: Icon(Icons.send),
                    backgroundColor: Colors.redAccent,
                  ),
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}