flutter 使用socket io 和 EventBus 開發(fā)及時(shí)通訊

1、

網(wǎng)上找一圈,關(guān)于flutter及時(shí)通訊的文章太少了。實(shí)際項(xiàng)目需要用socket io 來實(shí)現(xiàn)客戶端的消息收發(fā),服務(wù)端已經(jīng)寫好了。
一開始的思路是使用 socket io + 數(shù)據(jù)庫,但數(shù)據(jù)庫用起來是個(gè)麻煩事,其實(shí)socket io 目前現(xiàn)有的框架集成到項(xiàng)目中總是有各種各樣的bug和兼容問題。

所以在折騰很久之后選擇了一個(gè)降級的socket io 庫。目前沒有發(fā)現(xiàn)什么問題,結(jié)合eventbus實(shí)現(xiàn) 消息在客戶端的傳遞。


在這里插入圖片描述
2、依賴

pubspec.yaml

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

一般是在首頁,該頁面一般不會被銷毀,所以在該頁面注冊Event,能保證消息的實(shí)時(shí)的接收,同時(shí)鏈接socket io查詢所有的聊天室。

1、
這里我封裝一個(gè)socketUtils來做消息接收的驗(yàn)證

on方法是接收事件,和服務(wù)端約定好對應(yīng)的key,然后在接收到消息后通過eventBus分發(fā)給相應(yīng)的頁面。

class SocketUtils {
  static SocketIOManager manager;
  static SocketIO socket;
  static Future socketTo() async {
    print('登錄IM');
    manager = SocketIOManager();
    //該部分需要根據(jù)自己實(shí)際業(yè)務(wù)實(shí)現(xiàn)
    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();
    }
//下面是客戶端發(fā)送數(shù)據(jù)包
  //獲取會話列表
  static getRooms() {
    if (socket != null) {
      print('獲取會話列表');
      socket.emit('rooms', []);
    }
  }
//發(fā)送消息
 static sendMsg(MessageBean messageBean) {
    //實(shí)時(shí)更新到聊天界面
    eventBus.fire(messageBean);
    if (socket != null) {
      socket.emit('sendMessage', [
        {
            'msg': messageBean.msg
          }
        }
      ]);
    }
  }  

2、消息列表
在初始化的時(shí)候調(diào)用

SocketUtils.socketTo();

如果鏈接成功會自動拉取一次getRooms(),當(dāng)然如果鏈接失敗,重試也可以直接使用該方法,或者鏈接成功,但是獲取rooms失敗,那就直接調(diào)用

SocketUtils.getRooms();

然后在消息列表注冊eventbus的監(jiān)聽

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注冊監(jiān)聽,收到消息后分別處理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容