当前位置: 首页 > news >正文

11.2.1.项目整体架构和技术选型及部署

1 项目简介

1. 支持HTTP请求,掌握HTTP API + json的请求相应

2. 支持Websocket,掌握json做序列化和反序列化

3. 支持多房间聊天 多个主题聊天

4. 支持多人聊天

5. 支持MySQL存储用户信息

6. 支持Redis缓存token,存储聊天消息

2 项目架构

4.1 项目框架

4.2 聊天逻辑

4.3 数据存储

MySQL:存储用户信息,在0voice_chatroom数据库对应的users表。

Redis:存储房间消息和用户cookie

  • 房间消息:使用redis的stream结构,key为房间id,value为房间的聊天消息
  • 用户cookie,使用redis的string结构,key为cookie,value为用户id,cookie默认有效期是1天,超过1 天redis就将他删除,就需要用户重新登录。

4.4 消息格式

4.4.1 HTTP请求消息格式

create_account创建账号消息

API URL:http:xxx.xxx.xxx.xxx:3000/api/create-account

{"username": "darren","email": "326873713@qq.com","password": "xxxxxxx"
}
login登录消息

API URL:http:xxx.xxx.xxx.xxx:3000/api/login

{"email": "326873713@qq.com","password": "xxxxxxx"
}

4.4.2 Websocket交互消息格式

1 刚websocket连接的消息

服务器回应客户端的数据,拉取已有的聊天室以及对应的聊天消息。

{"type": "hello","payload": {"me": {"id": 5,"username": "小鸭子米奇"},"rooms": [{"id": "beast","name": "程序员老廖","hasMoreMessages": false,"messages": [{"id": "1726840364728-0","content": "222222","user": {"id": 5,"username": "小鸭子米奇"},"timestamp": 1726840364726},{"id": "1726840317055-0","content": "222","user": {"id": 5,"username": "小鸭子米奇"},"timestamp": 1726840317055}.......]},{"id": "async","name": "Boost.Async","hasMoreMessages": false,"messages": [{"id": "1726839255147-0","content": "2","user": {"id": 5,"username": "小鸭子米奇"},"timestamp": 1726839255146},{"id": "1726836482227-0","content": "22222222","user": {"id": 5,"username": "小鸭子米奇"},"timestamp": 1726836482218}]},{"id": "db","name": "Database connectors","hasMoreMessages": false,"messages": []},{"id": "wasm","name": "Web assembly","hasMoreMessages": false,"messages": []}]}
}

2 聊天消息格式

发送端:比如用户名:小鸭子米奇,用户id:5发送的消息,此时会携带cookie

{"type": "clientMessages","payload": {"roomId": "beast","messages": [{"content": "这是小鸭子发送的消息"}]    }
}

经过服务端处理后转发给其他接收者的消息,此时消息类型type 变为“serverMessages”,message字段增 加了消息id,并增加了用户信息 "user": { "id": 5, "username": "小鸭子米奇"},,以及时间戳timestamp。

{"type": "serverMessages","payload": {"roomId": "beast","messages": [{"id": "1726839290525-0","content": "这是小鸭子发送的消息","user": {"id": 5,"username": "小鸭子米奇"},"timestamp": 1726839290524}]}
}

发送端的json数据只所以不带用户信息,是因为其可以通过cookie从redis读取email,再根据 email去 MySQL查询到username和user id,这里这个设计可以了解,但这种做法虽然减少了客户端发送的数据量。

3 获取历史消息

请求类型 type: "requestRoomHistory",

结构:roomId 房间id, firstMessageId消息起始id

应答结构:

  • roomId 房间id
  • messages 对应的消息组
  • hasMoreMessages 是否还有消息
  • type 类型 roomHistory

redis演示:

输入消息:

127.0.0.1:6379> DEL mystream127.0.0.1:6379> XADD mystream * value 0
1736936425901-0
127.0.0.1:6379> XADD mystream * value 1
1736936431129-0
127.0.0.1:6379> XADD mystream * value 2
1736936437028-0
127.0.0.1:6379> XADD mystream * value 3
1736936442697-0
127.0.0.1:6379> XADD mystream * value 4
1736936447601-0
127.0.0.1:6379> XADD mystream * value 5
1736936452204-0
127.0.0.1:6379> XADD mystream * value 6
1736936457168-0
127.0.0.1:6379> XADD mystream * value 7
1736936461668-0
127.0.0.1:6379> XADD mystream * value 8
1736936467004-0
127.0.0.1:6379> XADD mystream * value 9
1736936473984-0
127.0.0.1:6379> XADD mystream * value 10
1736936479128-0
127.0.0.1:6379> XADD mystream * value 11
1736936485528-0
127.0.0.1:6379>

分页读取,先读取最近的数据

1. 第一次拉取

XREVRANGE mystream + - COUNT 5

返回结果:

127.0.0.1:6379> XREVRANGE mystream + - COUNT 5
1736936485528-0
value
11
1736936479128-0
value
10
1736936473984-0
value
9
1736936467004-0
value
8
1736936461668-0
value
7

2. 第二次拉取

假设上次拉取的最后一条消息 ID 是 1736936461668-0 ,则下一次拉取的命令为:

127.0.0.1:6379> XREVRANGE mystream (1736936461668-0 - COUNT 5
1736936457168-0
value
6
1736936452204-0
value
5
1736936447601-0
value
4
1736936442697-0
value
3
1736936437028-0
value
2

3. 第三次拉取

假设上次拉取的最后一条消息 ID 是 1736936437028-0 ,则下一次拉取的命令为:

127.0.0.1:6379> XREVRANGE mystream (1736936437028-0 - COUNT 5
1736936431129-0
value
1
1736936425901-0
value
0

4 注意事项

1. 消息 ID 格式

Redis Stream 的消息 ID 是一个时间戳加序列号的形式,例如 1672531199000-0 。 Redis Stream 中的消息 ID 是一个特殊的格式,由两部分组成:时间戳和序列号,格式如下:

<毫秒时间戳>-<序列号>

例如,消息 ID 1736936425901-0 的格式解析如下:

1. 时间戳部分 ( 1736936425901 )

这是一个以毫秒为单位的 Unix 时间戳。 1736936425901 表示从 1970 年 1 月 1 日 00:00:00 UTC 开始计算的毫秒数。 转换为人类可读的时间:

date -d @1736936425

输出:

Wed 15 Jan 2025 06:20:25 PM CST

2. 序列号部分 ( 0 )

这是一个自增的序列号,用于区分同一毫秒内生成的多个消息。 如果在同一毫秒内添加了多条消息,Redis 会自动递增序列号。 例如:

第一条消息: 1736936425901-0 第二条消息: 1736936425901-1 第三条消息: 1736936425901-2

2. ( 符号的作用

在消息 ID 前加 ( 表示不包含该消息 ID,从下一条消息开始拉取。

3. 空结果

如果返回空结果,表示已经拉取完所有消息。

4. 性能

XREVRANGE 的性能较高,适合用于实时消息处理场景。

5. 可以自定义消息id

127.0.0.1:6379> DEL mystream
1
127.0.0.1:6379> XADD mystream 1 value 1
1-0
127.0.0.1:6379> XADD mystream 2 value 2
2-0

也可以手动指定消息 ID,但必须满足以下条件:

  • 时间戳部分必须大于 Stream 中已有的最大时间戳。
  • 序列号部分必须大于同一时间戳内的最大序列号。

Redis Stream 的消息 ID 格式为<毫秒时间戳>- <序列号>- ,用于唯一标识和排序消息。时间戳部分表示消息 的创建时间,序列号部分用于区分同一毫秒内的多条消息。

参考链接:0voice · GitHub


文章转载自:

http://OzbFBEjF.bxczt.cn
http://zmKGYUyd.bxczt.cn
http://IDuK6aJ1.bxczt.cn
http://SfecHsh3.bxczt.cn
http://seQyQ9sY.bxczt.cn
http://jA1nsZPZ.bxczt.cn
http://wAlSPotS.bxczt.cn
http://QOZDiTvS.bxczt.cn
http://eI2y2Y54.bxczt.cn
http://wmswuvsc.bxczt.cn
http://rqTLAPo1.bxczt.cn
http://upnNBlit.bxczt.cn
http://Fv5tI4mg.bxczt.cn
http://aQorrQCG.bxczt.cn
http://503tNIoz.bxczt.cn
http://bcIE21Oz.bxczt.cn
http://UrUH0O3S.bxczt.cn
http://yGJN7b2E.bxczt.cn
http://PX0b7ozM.bxczt.cn
http://0ttC2m43.bxczt.cn
http://IoVmCg3K.bxczt.cn
http://OLhyWnIm.bxczt.cn
http://F75iSMxT.bxczt.cn
http://YhhB76Ie.bxczt.cn
http://8kBB4TpC.bxczt.cn
http://CnSlg7GJ.bxczt.cn
http://hi6Yu2FF.bxczt.cn
http://EcBQ3aqB.bxczt.cn
http://xTQURP6K.bxczt.cn
http://xtgkrJuH.bxczt.cn
http://www.dtcms.com/a/372224.html

相关文章:

  • [C++刷怪笼]:set/map--优质且易操作的容器
  • zotero扩容
  • 20250907_梳理异地备份每日自动巡检py脚本逻辑流程+安装Python+PyCharm+配置自动运行
  • UserManagement.vue和Profile.vue详细解释
  • Python进阶编程:文件操作、系统命令与函数设计完全指南
  • 【redis 基础】redis 的常用数据结构及其核心操作
  • 美团大模型“龙猫”登场,能否重塑本地生活新战局?
  • nats消息队列处理
  • k8s镜像推送到阿里云,使用ctr推送镜像到阿里云
  • Ubuntu Qt x64平台搭建 arm64 编译套件
  • IO性能篇(一):文件系统是怎么工作的
  • SQL Server——基本操作
  • nginx详解
  • 硬件开发1-51单片机4-DS18B20
  • 【LLIE专题】LYT-Net:一种轻量级 YUV Transformer 低光图像增强网络
  • 数据库造神计划第二天---数据库基础操作
  • TypeORM 入门教程之 `@OneToOne` 关系详解
  • 嵌入式解谜日志之数据结构—基本概念
  • make_shared的使用
  • 《九江棒球》未来十年棒垒球发展规划·棒球1号位
  • agentscope1.0安装与测试
  • Shell 脚本自动安装 Nginx
  • 《探索C++11:现代语法的内存管理优化“性能指针”(下篇)》
  • Basic Pentesting: 1靶场渗透
  • NAS自建笔记服务leanote2
  • 对比Java学习Go——程序结构与变量
  • 【JavaWeb】一个简单的Web浏览服务程序
  • [C/C++学习] 7.“旋转蛇“视觉图形生成
  • webhook(Web 钩子)是什么?
  • 《2025年AI产业发展十大趋势报告》四十三