千家信息网

Android Flutter基于WebSocket怎么实现即时通讯功能

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍"Android Flutter基于WebSocket怎么实现即时通讯功能",在日常操作中,相信很多人在Android Flutter基于WebSocket怎么实现即时通讯功能问题上存
千家信息网最后更新 2026年10月31日Android Flutter基于WebSocket怎么实现即时通讯功能

这篇文章主要介绍"Android Flutter基于WebSocket怎么实现即时通讯功能",在日常操作中,相信很多人在Android Flutter基于WebSocket怎么实现即时通讯功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Android Flutter基于WebSocket怎么实现即时通讯功能"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

联系人界面构建

我们在聊天前,需要选择对应的联系人进行单聊,因此需要构建一个联系人列表。这里我们使用简单的 ListView.builder+Mock 数据构建联系人列表。界面如下所示,其中关键的就是点击联系人时将联系人的 id通过路由传递过去,以便发送消息时通过用户 id指定接收用户。

return ListTile(  leading: _getRoundImage(contactors[index].avatar, 50),  title: Text(contactors[index].nickname),  subtitle: Text(    contactors[index].description,    style: TextStyle(fontSize: 14.0, color: Colors.grey),  ),  onTap: () {    debugPrint(contactors[index].id);    RouterManager.router.navigateTo(context,        '${RouterManager.chatPath}?toUserId=${contactors[index].id}');  },);

聊天界面的实现

我们将发送的消息放在右边,将接收到的消息放在左边,居左还是居右通过 Container 的 margin 来实现。至于区分,通过消息对象的fromUserId 来区分,如果 fromUserId 和当前用户id 一致,则是发送出去的消息,否则就是接收到的消息。在这里我们因为还没有用户体系,先将当前的用户 id 写死。为了实现模拟器之间的聊天,我们一个模拟器设置为 user1,一个设置为 user2。界面也是使用ListView.builder(万能不?)构建。

return ListView.builder(  itemBuilder: (context, index) {    MessageEntity message = messages[index];    double margin = 20;    double marginLeft = message.fromUserId == 'user1' ? 60 : margin;    double marginRight = message.fromUserId == 'user1' ? margin : 60;    return Container(      margin: EdgeInsets.fromLTRB(marginLeft, margin, marginRight, margin),      padding: EdgeInsets.all(15),      alignment: message.fromUserId == 'user1'          ? Alignment.centerRight          : Alignment.centerLeft,      decoration: BoxDecoration(          color: message.fromUserId == 'user1'              ? Colors.green[300]              : Colors.blue[400],          borderRadius: BorderRadius.circular(10)),      child: Text(        message.content,        style: TextStyle(color: Colors.white),      ),    );  },  itemCount: messages.length,);

聊天界面的一个特点是会接收StreamProvider 推送的最新的消息,为了统一,我们将接收消息和发送消息都通过StreamProvider推送更新界面。

// 发送消息时将消息加入到流控制器中void sendMessage(String event, T message) {  _socket.emit(event, message);  _socketResponse.sink.add(message);}// 接收消息时也加入到流控制器中_socket.on(recvEvent, (data) {  _socketResponse.sink.add(data);});

这样不管是接收消息还是发送消息都会通过 StreamProvider 重新构建聊天界面。那问题来了,聊天列表数据如何刷新呢?

消息界面的 MultiProvider

消息界面需要接收 StreamProvider 的消息流,还需要使用消息列表数据,这里我们使用了 MultiProvider。其中消息发送框和聊天界面共用 ChatMessageModel(仅为演示,实际可以拆分开)。

final chatMessageModel = ChatMessageModel();//...body: Stack(  alignment: Alignment.bottomCenter,  children: [    MultiProvider(      providers: [        StreamProvider?>(            create: (context) => streamSocket.getResponse,            initialData: null),        ChangeNotifierProvider.value(value: chatMessageModel)      ],      child: StreamDemo(),    ),    ChangeNotifierProvider.value(      child: MessageReplyBar(messageSendHandler: (message) {        Map json = {          'fromUserId': 'user1',          'toUserId': widget.toUserId,          'contentType': 'text',          'content': message        };        streamSocket.sendMessage('chat', json);      }),      value: chatMessageModel,    ),]//...

其中ChatMessageModel即消息列表状态数据,里面只有一个消息对象数组和一个添加消息方法,以及一个 content 属性是给消息回复框使用的。

这里就有一个问题,StreamProvider 推送 StreamSocket过来的消息的时候, ChatMessageModel 其实是不知道的。如果要知道,一个办法就是在 StreamSocket 引用 ChatMessageModel对象,然后调用其 addMessage 方法添加消息。但是这样会增加两个类的耦合。还有一种方式是取巧的方式了,那就是 StreamdDemo的 build 方法能够获取到 StreamSocket 推送的最新消息,在这里读取到最新的消息后就可以添加到消息列表了。由于前面我们发送消息和接收消息都将消息加入到了消息流中,这样处理方式就统一了。

这种方式需要注意,Provider 不允许在组件的build 方法中再次调用类似 notifyListeners 的方法通知该组件刷新,因此在 ChatMessageModel的 addMessage 方法里不可以使用notifyListeners来通知组件刷新,否则会出现同一组件刷新冲突。实际上,因为另一个Provider 已经通知该组件刷新了,因此也没必要再通知了。当然,这仅仅是一种取巧方法,假设这个addMessage 方法还需要通知其他组件刷新,那这种形式就就不可取了。

class ChatMessageModel with ChangeNotifier {  List _messages = [];  List get messages => _messages;  String content = '';  void addMessage(Map json) {    _messages.add(MessageEntity.fromJson(json));  }}

这里我们先不考虑这种情况,StreamDemo 的 build关于这部分的处理方法如下,这里对于吧 ChatMessageModel 也就不需要使用 watch 方法了,完全依赖于 StreamProvider 的流推送来更新组件。每次发送消息或接收消息后,构建时在返回组件树前就更新了消息列表数据了,因此也能保证数据是最新的。其实,相当于我们投机取巧实现了两个 Provider之间的数据交互。

@overrideWidget build(BuildContext context) {  Map? messageJson = context.watch?>();  if (messageJson != null) {    context.read().addMessage(messageJson);  }  List messages = context.read().messages;  // ListView 部分}

运行效果

来看一下运行效果,模拟器的好处就是可以开多个调试。效果是实现了,不过实际即时聊天比这个复杂很多,而且一般也不会用 Socket,但是如果 App 内部要实现应用打开后的即时消息推送,WebSocket 是一个不错的选择。源码已经提交,后端和Flutter 代码分布如下:

Flutter Provider 部分代码(null safety 版本)

后端代码(Express 版本)

到此,关于"Android Flutter基于WebSocket怎么实现即时通讯功能"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

消息 方法 界面 组件 数据 联系人 联系 就是 用户 推送 功能 通讯 方式 学习 代码 实际 对象 效果 模拟器 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技互联网 互联网科技产业 云信互联网科技有限公司 科技创新与互联网经济 鸠鸠互联网科技 科技互联网公司装修 卓越科技(互联网 ) 艾特科技互联网 华中科技大学互联网 佰商互联网科技有限公司 哈尔滨秒房互联网科技有限公司 成都玖崟互联网科技有限公司乐商圈怎么样 新华互联网科技2019 本届互联网博览会上的黑科技 洛阳共同富裕互联网科技有限公司 互联网数据科技专业 信承诺互联网科技有限公司 绵阳真晨互联网科技有限公司 三亚科技创新互联网基地 宁波允成互联网科技有限公司 天下捷融互联网科技 甘肃拓世互联网科技有限公司 宁波青枫互联网科技有限公司 昭通云南众福互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 互联网科技商业 移动互联网年度科技创新 银行科技岗属于互联网吗 郑州欣桑互联网科技有限公司 求路客互联网科技电话
0