开发笔记——多人聊天项目开发心得

前言

不断写作,不断成长。

最近在使用Flutter开发了交流模块内容,在开发中不断出现很多小BUG以及不断维护功能,经过沉淀最后写下该文章以记录成长,避免重复踩坑

技术栈

因为开发的是应用,所以则使用Flutter进行页面涉及以及相关逻辑处理

使用WebSocket实现多人聊天

WebSocket结构

我所使用的WebSocket中的相关参数结构(仅供参考)

  • user_id 发送者ID
  • send_name 发送者名字
  • receive_id确定接收者(多个以“,”分隔开,全部用all)
  • message发送内容(不得超过100字)

WebSocket服务端中会对每次发包的receiver_id进行验证处理,必须为数据库中的uid

Flutter发包示例

var packet = {
      "user_id" : userId,
      "send_name": name,
      "message": message,
      "title": title,
      "type": 2
    };
//发包
socketHandle.sink.add(packet)

功能模块

重要的就以下俩个模块

最近聊天模块(Message)、聊天窗模块(Chat)

最近聊天模块

这里需要主要的事项有很多,因为会出现三种情况注:(一定要切记这三种情况出现,我就是在这里出现问题)

为了方便介绍功能实现,这里简化A为用户A,B为用户B。

1、当A发送至消息给B B未发送消息给A过

2、当B未发送过给A消息 B只做接收者

3、当B发送消息和A A-B实现点对点聊天

切记,在这里实现最近聊天模块是一定要注意这三个点!!!

排序处理

后台有一张表为:ChatMessage 包含了几个重要参数

send_id、receiver_id、message、time

在获取完所有消息列表后,可以通过List的sort方法

示例

    recordList.sort((a,b)=> DateTime.parse(b?.time ?? "").compareTo(DateTime.parse(a?.time ?? "")));

这样可以获取到消息的完整排序列表

转化为最近聊天对象

最近聊天实体类我是这样设计的

class RecordLately {
  String? _portrait;
  String? _title;
  String? _message;
  String? _time;
  bool? _selected;
}

portrait 头像、title为最近聊天的标题、message消息,time时间用来排序

转化数据库ChatMessage为最近聊天实体类方法

  @override
  RecordLately createRecordLately(ChatMessage ChatMessage,[int? recordId]) {
    String title = "";
    String portrait = "";
    String message = ChatMessage?.message ?? "";
    //这里的type指的是联系人/群聊
    int type = ChatMessage.groupId == null ? 0 : 1;
    String time = ChatMessage?.time ?? "";
    switch(type){
      case 0:
        int receiverId = recordId ?? 0;
        User receiverUser = getUserById(receiverId);
        title = receiverMeetingUser.username!;
        //1男 2女
        portrait = receiverUser.gender == 1 ? PortraitEnum.MAN.assets :PortraitEnum.WOMAN.assets;
        break;
    }
    var json = {
      "title": title,
      "portrait": portrait,
      "message": message,
      "time": time,
      "type": type,
      "selected": false
    };
    RecordLately recordLately = RecordLately.fromJson(json);
    return recordLately;
  }

之后传递到Message中初始化赋值渲染即可!

聊天模块

这个地方重点来了,涉及到title和交流信息数据 最好是还需要设计一个RecordInfo实体类对象用来做消息记录

RecordInfo实体类如下

class RecordInfo {
  String? _message;
  int? _type;
  String? _time;
  int? _sort;
}

RecordInfo用来做ChatMessage数据库实体类的包装类

message最新消息、type区分是作为接收者还是发送者、time时间用来排序、sort用来当每条消息的记录排序

绑定消息记录

这里需要将ChatMessage进行全局化,意味着你可以放置在Common文件夹下定义Static类型

需要给予一个根据发送者id和接收者id的方法进行过滤消息列表

Flutter示例代码

  /*
   * 通过接收者id获取所有相关的会议聊天信息
   */
  List<ChatMessage> selectMessageListByReceiverId(int sendId,int receiverId){
    return state.ChatMessage.where((element){
      return sendId == element.sendId && receiverId == element.receiverId;
    }).toList();
  }

拥有了这个,已经完成了Chat所需要具备的参数

定义 Map类型的recordMap key为title,value为List<RecordInfo>

转化ChatMessage为RecordInfo

示例方法

  /*
   * 转换聊天记录表为聊天数据实体对象
   */
  List<RecordInfo> parseMessageToRecordInfo(List<ChatMessage> Message,{int type = -1}){
    List<RecordInfo> recordInfo = [];
    for(int i = 0;i<Message.length;i++){
      var element = Message[i];
      Map<String,dynamic> recordMap = {
        "message": element.message,
        //type 0> 自己 1别人
        "type" : type == -1 ? element?.styleType : type,
        "time": Utils.parseDateTimeByString(element?.time ?? "").toString(),
        "sort": i
      };
      RecordInfo info = RecordInfo.fromJson(recordMap);
      print('RecordInfo: message: ${info.message}, Time: ${info.time}, Sort: ${info.sort}');
      recordInfo.add(info);
    }
    return recordInfo;
  }

最后通过用户在Message页点击某个人,之后通过路由携带title参数进行跳转,再通过title解析相关ChatMessage即可!

发送消息

关于在Chat页中,发送消息时所需要注意的事项

  • 插入接口数据
  • 重载全局ChatMessage数据
  • 重新渲染当前页面数据
  • 发送聊天包

聊天包格式在有写

WebSocket监听处理

前面提到发送消息时会发包,在WebSocket监听中,我们需要做如下几个事项

  • 获取包中携带的data参数列表
  • 重载全局ChatMessage数据(必要性,不然会导致Chat页和Message页数据不同步)
  • 根据data中携带的title数据,在最近聊天数据列表中进行title查询索引
  • 根据最近聊天列表索引进行替换相关最新信息
  • 重载Chat页&Message页路由即可!

其实大致交流模块内容就是针对于WebSocket进行处理,在对于业务逻辑上,只要注意以上几个问题即可!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇