# goimv1
**Repository Path**: g_night/goimv1
## Basic Information
- **Project Name**: goimv1
- **Description**: 基于golang实现的im实时聊天系统 - MVC架构
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 2
- **Created**: 2021-10-09
- **Last Updated**: 2025-01-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: go-main
## README
**goimv1**
本项目基于gin、gorm实现,单体应用实现即时通讯。
# 介绍
基于golang实现的im实时聊天系统 - MVC架构
技术:gin + mysql + redis + gorm
- 注册登录模块:
1. 邮箱注册`tool.mail_tool` 支持多邮箱注册,由项目:[ay-mail-model](https://gitee.com/g_night/ay-mail-model) 抽取核心逻辑实现
2. `middleware.Authentic()`身份校验,登录获取`token`
- 用户管理模块:
1. 设置个人头像,存储逻辑提供模板,建议自建or租用`cos平台`,分`bucket`存储更佳
2. 获取用户信息,返回个人信息模板:
邮箱(账户) + 昵称 + 头像 + 用户状态码
- 好友关系模块:
1. 用户查找,支持`mailbox`、`nickname`查找
2. 添加好友、好友申请显示、同意好友申请,采用`redis - list` 实现申请推送
3. 删除好友,支持单方向删除,删除后另一方发起聊天会被通知`发送失败`
- 聊天模块:
1. 私发信息,发送信息`redis - rpush list`
2. 接收消息,登陆后会自动`redis - lpop list`取出信息
- 待续
# 业务流程
## 注册业务
用户需要绑定`邮箱`实现个人注册,邮箱作为`唯一值`标识个人,同理这个标识也能被:电话、学号、身份证号等其他具有唯一性的标识字段替代
1. 页面提供`邮箱验证码`申请:
- 检测到存在被注册 --> 返回:提示已注册,跳转登陆界面
- 生成邮件验证码:`randWord`
- 发送验证码到指定邮箱 --> 失败:提示发送失败,邮箱不合法
- 记录到`redis`,设置过期时间 15min
2. 创建用户:
- 检测请求合法性,即所需字段是否完整
- 检测到存在被注册 --> 返回:提示已注册,跳转登陆界面
- 检测验证码不合法 -> 返回:验证码错误
- 生成`token`返回,自动登录
3. 登录用户:
- 检测到未注册 --> 返回:提示未注册,跳转注册界面
- 判断密码正确性
- 生成`token`返回,登陆成功
## 用户管理
用户管理模块允许用户修改头像、个性签名等个人资料,后续可以基于用户标识继续拓展更多功能
该模块的业务流程前面都是(下面表述的流程中会忽略这两个,提前在这说明):
- 所需字段校验
- token合法性校验 --> `middleware.Authentic`中间件
1. 头像修改:
- 上传到本地 or 云端cos平台,获得存储路径`headURL `
- 更新数据库`usr` 的`head_url`字段
2. 获取用户信息:
- 根据 `mailbox`获取到个人信息 --> `model.Ods`
## 好友关系模块
本模块用于好友之间的关系管理,目前支持单向关系,即一方删除出发送信息否则不会被告知对方已删除。后续这个好友关系可以继续拓展,比如设置`标签`来区分不同的好友等级,`secret`字段亦可以用于用户之间的对话加密,保证数据安全性(需要自己实现)
1. 好友查询:
- 支持`mailbox` || `nickname`两种方式
- 查询数据库返回`model.UsrOds`
2. 好友请求:
- 检查用户不存在 --> 返回:用户不存在
- 生成好友请求日志`FriendReqLog`插入到数据库
- 好友请求日志记录转换为`FriendReqOds` 插入到对应用户的redis
3. 好友请求显示:
- 读取redis --> 不断`lpop`读出好友请求
4. 好友请求通过:
- 检查请求记录合法性,查询`friend_req_log`
- 生成`Relationship`,插入双方关系记录,支持初次添加 or 关系修复
5. 好友关系显示:
- 根据唯一字段查询个人好友,返回`model.FriendshipOds`
6. 删除好友:
- 查询是否存在该好友
- 删除好友,单方向删除
- 删除聊天的`redis-key`
## 聊天模块
聊天模块基于redis的`list`结构实现,不断插入新的信息,这样的坏处是多端登录记录是`不统一`的,但是可以基于`chat_log`来实现多端统一,需要自己实现
1. 私发信息:
- 首先比较字符串:长度小的在前,长度相同则直接比较,选择小的在前 作为`key` -> 方法 `service.compareAndSwap`
- 读取redis看是否存在key,不存在则读取数据库,查看双方是否为好友, 一方不是 -> 返回410
- 存入key,value为二者的`secret`
- 记录信息到 `model.ChatLog`
- 将信息存到接收方的redis队列中,存储对象 `model.ChatOds`
2. 接收信息:
- 读取`redis`队列
- 防止一次弹出过多,一次最多50条
# 技术tips
- 密码、聊天记录等重要信息不要明文存储:密码采用的加密选择要慎重,采用的算法需要存档记录
- `gorm`生成model可以采用自动化工具,推荐:[grom-model-自动生成](https://gitee.com/g_night/gorm-model-create)
- 配置信息代码解耦,最好是能远端加密存储配置文件,拉去映射到结构体更好,同时可以实现`热加载`配置
**待续……**