flutter 使用socket io 和 EventBus 开发及时通讯

1、

网上找一圈,关于flutter及时通讯的文章太少了。实际项目需要用socket io 来实现客户端的消息收发,服务端已经写好了。
一开始的思路是使用 socket io + 数据库,但数据库用起来是个麻烦事,其实socket io 目前现有的框架集成到项目中总是有各种各样的bug和兼容问题。

所以在折腾很久之后选择了一个降级的socket io 库。目前没有发现什么问题,结合eventbus实现 消息在客户端的传递。
flutter 使用socket io 和 EventBus 开发及时通讯

2、依赖

pubspec.yaml

  # socket-io
  adhara_socket_io: ^0.2.0
  # 消息订阅
  event_bus: ^1.1.0
3、消息列表

一般是在首页,该页面一般不会被销毁,所以在该页面注册Event,能保证消息的实时的接收,同时链接socket io查询所有的聊天室。

1、
这里我封装一个socketUtils来做消息接收的验证

on方法是接收事件,和服务端约定好对应的key,然后在接收到消息后通过eventBus分发给相应的页面。

class SocketUtils {
  static SocketIOManager manager;
  static SocketIO socket;
  static Future socketTo() async {
    print('登录IM');
    manager = SocketIOManager();
    //该部分需要根据自己实际业务实现
    String token = await SPUtils.getToken();
    print(token);
    if(token!=null) {
      token = token.substring(7);
    }
    print(token);
    //配置socket链接信息
    SocketOptions socketOptions = new SocketOptions(
      Api.SOCKET_IO_URL,
      query: {
        'token': token,
        'source': 'CONSULTANT',
      },
      transports: [Transports.WEB_SOCKET, Transports.POLLING],
      enableLogging: false,
    );
    socket = await manager.createInstance(socketOptions);
    socket.onConnect((res) {
      print('onConnect--------socket链接成功---------');
      getRooms();
    });
    socket.on('connect', (res) {
      print('connect----------');
    });
    //房间列表
    socket.on('rooms', (rooms) {
      eventBus.fire(new ResultEvent(rooms));
    });
    //消息历史
    socket.on('history', (data) {
      LogUtil.e('消息历史:' + data.toString());
      eventBus.fire(new MsgHistoryResultEvent(data));
    });
    socket.on('delete', (data) {
      print('消息删除delete:' + data.toString());
    });
    socket.on('message', (data) {
      print('新消息:' + data.toString());
      eventBus.fire(new MessageEvent(data));
    });
    socket.connect();
    }
//下面是客户端发送数据包
  //获取会话列表
  static getRooms() {
    if (socket != null) {
      print('获取会话列表');
      socket.emit('rooms', []);
    }
  }
//发送消息
 static sendMsg(MessageBean messageBean) {
 	//实时更新到聊天界面
    eventBus.fire(messageBean);
    if (socket != null) {
      socket.emit('sendMessage', [
        {
            'msg': messageBean.msg
          }
        }
      ]);
    }
  }  

2、消息列表
在初始化的时候调用

SocketUtils.socketTo();

如果链接成功会自动拉取一次getRooms(),当然如果链接失败,重试也可以直接使用该方法,或者链接成功,但是获取rooms失败,那就直接调用

SocketUtils.getRooms();

然后在消息列表注册eventbus的监听

StreamSubscription streamSubscription;
streamSubscription = eventBus.on().listen((e) {
      switch (e.runtimeType) {
        case ResultEvent:
          //会话列表
          setState(() {
            msgList = [];
            for (var i = e.data.length - 1; i >= 0; i--) {
              msgList.add(new User.fromJson(e.data[i]));
            }
            if (e.data.length == 0) {
              emptyText = '暂无消息';
            }
          });
          break;
        case MessageEvent:
          //新消息
          SocketUtils.getRooms();
          break;
        case UndoEvent:
          //撤回
          SocketUtils.getRooms();
          break;
      }
    });

3、消息详情

同上,使用eventbus注册监听,收到消息后分别处理

上一篇:mac下的改装人生——把主硬盘换成ssd


下一篇:vue 中 EventBus 实现组件通信