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