Combining bloc and websockets



我试图在两个方向上使用websockets(即,当websocket接收到消息时,触发事件以及当状态发出时,通过websocket发送消息)。我对flutter还很陌生,但是用其他语言写过类似风格的代码(消息队列和websockets),但是我真的很努力地想知道如何构建一切,以便它在flutter中工作。

我有一个基本类打开websocket并等待事件

class WebsocketManager {
final BuildContext context;
late IOWebSocketChannel channel;
WebsocketManager(this.context);
void connect(){
channel = IOWebSocketChannel.connect(Uri.parse(wsBaseUrl));
channel.stream.listen(
(msg) {
//process msg 
BlocProvider.of<SomeBloc>(context).add(MessageReceived(msg));
}
);
}
}

这工作得很好(尽管必须通过BuildContextin感觉有点错误)。问题在于倾听新出现的州。我认为我可以做这样的事情

BlocListener<SomeBloc, SomeState>(
listener: (context, state) {
if(!sendMessage(SomeMessage()))
});

但是这个监听器永远不会触发。如果我将相同的代码作为Widget的子组件,那么它就可以正常工作,所以我假设BlockListener必须是Widget的子组件。

我的问题是,有没有一种方法使用BlocListener(或一些替代方案),而不是一个小部件的孩子?

或者,有一个更好的方法,我可以结构我的代码,使它可以访问websocket和集团?

感谢

首先,BlockListener必须是与块一起提供的小部件的子组件。

是的,我不会传递BuildContext到WebsocketManager。我会把它翻转一下,让它更干净一点。

你怎么做当然取决于你的UI应该如何基于事件和状态的行为。但是为了保持我的示例简单,我在下面有一个建议,其中一个Widget(可能是整个路由)正在基于websocket消息侦听和更新。你当然可以这样做,这样整个应用程序都受到websocket的影响,但这是"下一步"。

块应该是你的WebsocketManager和UI之间的粘合剂。因此,我建议让您的Bloc在适当的地方创建(提供)到一个Widget。该集团持有一个WebsocketManager的实例(可能是Singleton?)在使用WebsocketManager.connect()建立连接的块中有一个方法和相应的状态。但是,不是在监听回调中做....add(MessageReceived(msg))的事情,而是有一个方法(可能是您的connect()方法)返回Stream<type of msg>并让监听回调yield msg。然后,你可以在你的模块中为WebsocketManager的流设置一个StreamSubscription,然后根据从websocket接收到的内容发出状态并采取行动。

我建议你也将msg从监听回调转换为你自己的域对象,并在流中产生它,这样你的块就不会严格依赖于WebsocketManager的msg类型。

这样你的WebsocketManager只在数据层做'websocket-stuff',你让你的bloc在应用层做逻辑,这将让你的UI基于你的bloc发出的内容更新。

最新更新