easyim 是一个简单易用,二开友好,方便部署的即时通讯服务器。如数据量大、对性能有要求,请自行扩展,并将sqlite3
替换为其他数据库。
在线文档: https://imdocs.catmes.com
代码源于刘丹冰老师视频教程:8小时转职Golang工程师 - 即时通讯系统
下载并安装Go: https://golang.google.cn/doc/install
# 开启 module 功能
go env -w GO111MODULE=on
# 设置GO国内代理. 若执行 go mod tidy 命令提示模块下载失败. 请更换模块代理再重试 go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOPROXY=https://goproxy.io,direct
Windows环境下,如发现 cgo
报错,可能为 sqlite3
组件编译错误。请安装C编译器 TDM-GCC 或 Mingw-w64
# 加载依赖包
go mod tidy
# 首次运行,添加初始化参数--init,初始化数据库
go run . --init
# 正常开发时调试运行
go run .
# 编译为二进制文件. 然后直接运行./easyim(easyim.exe)
go build .
客户端调试:
# linux下使用nc命令调试
nc 127.0.0.1 8888
# 使用本项目 `examples` 目录中示例文件调试
go run client.go -ip 127.0.0.1 -port 8888
复制 env.default
文件为 .env
, 并更改新配置文件 .env
的配置项,以覆盖 env.default
配置文件的默认值
IM数据通讯的长连接,支持数据传输 json
, protobuf
两种格式。默认为 protobuf
。
如需更改,请在 .env
文件,添加配置项 MSG_FORMAT = "json"
,以覆盖默认值。
数据格式说明:
字段名 | 数据类型 | 释义 |
---|---|---|
id | string | 消息ID,字符串格式 |
seq | uint32 | 时序号,整型。确保消息按正确顺序显示。客户端按用户发送顺序,从小到大填写seq值。 |
from_user_id | string | 消息发送方ID |
to_user_id | string | 消息接收方ID |
chat_type | ChatType | 聊天类型(ChatType枚举类型:0单聊,1群聊) |
msg_type | MsgType | 消息类型(MsgType枚举类型:0文本,1图片,2语音,3视频,4事件,5系统通知) |
status | MsgStatus | 消息状态(MsgStatus枚举类型:0未发送,1已发送,2已送达,3已读取) |
content | string | 消息内容,字符串类型 |
access_token | string | 鉴权令牌,字符串类型。用户登录成功后获取 |
请参看 protobuf/msg.proto文件
# 下载 protoc 命令工具,用来生成特定语言的 protobuf 数据处理文件
# https://github.com/protocolbuffers/protobuf/releases
# 安装 protoc-gen-go 插件,解析protobuf协议数据为Go语言的数据处理文件
# go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# 根据msg.proto协议文件,在model目录,生成Go语言的protobuf数据处理文件
protoc --go_out=model protobuf/msg.proto
当 msg_type=4
时,代表当前通讯数据为一条事件消息
。 事件ID
定义如下表所示:
事件ID | 释义 |
---|---|
KEEP_ALIVE | 心跳事件 |
FRIEND_INVITE | 好友邀请 |
FRIEND_AGREE | 同意好友邀请 |
事件ID
为字符串,代表事件类型(如心跳事件, 好友邀请),事件消息的 content
字段内容为json字符串。
服务端给客户端发送的json数据,为统一格式: {"code":200,"msg":"SUCCESS","data":{"key":"KEEP_ALIVE"}}
字段 | 数据类型 | 释义 |
---|---|---|
code | 整数 | 状态码 |
msg | 字符串 | 提示信息 |
data | json对象 | 消息主体 |
key | 字符串 | 事件ID |
具体事件消息示例:
事件 | from_user_id | to_user_id | content |
---|---|---|---|
客户端上报心跳 | 客户端user_id | {"key":"KEEP_ALIVE"} | |
服务端响应心跳 | 客户端user_id | {"code":200,"msg":"SUCCESS","data":{"key":"KEEP_ALIVE"}} | |
客户端发送好友邀请 | 对方user_id | {"key":"FRIEND_INVITE"} | |
客户端收到好友邀请 | 邀请方user_id | {"code":200,"msg":"SUCCESS","data":{"key":"FRIEND_INVITE"}} | |
客户端同意好友邀请 | 被邀请user_id | 邀请方user_id | {"key":"FRIEND_AGREE"} |
心跳消息
是一种特殊的 事件消息
, 用于客户端向服务端发送周期性消息。因为服务端长期未收到消息,会主动断开连接。
- 发送原因: 用户一直未主动发消息,又要保持与服务端的长连接不断开,才能持续接收在线消息。
- 发送频率: 服务端有长期未收到消息,主动断开连接的
等待时间
, 客户端心跳发送周期
,稍小于该时间。 - 首次发送: 建立TCP连接后,客户端发送的首条消息必须为
心跳消息
,告诉服务端用户已上线。
心跳消息
发送方式,请参看 事件消息
介绍。
- 在
.env
文件中,设置MSG_FORMAT = "json"
- 进入 websocket 在线调试网页: https://websocketking.com/ 或 http://www.websocket-test.com/
- 输入连接地址. 如:
ws://127.0.0.1:8888
. 然后点击连接 - 连接成功后,在对话框中,发送符合规范的 json 格式数据,查看服务器数据响应。
- 如发送数据不符合规范,服务器会断开连接。
json格式数据示例:
{"id":"1630392697653039104","seq":0,"from_user_id":"1630381388895096832","to_user_id":"1630381388895666666","chat_type":0,"msg_type":0,"status":1,"content":"hello word.can you received ?","access_token":"aa.bbb.cc"}
# 全局安装 docsify 文档生成工具
npm i docsify-cli -g
# 文档初始化
docsify init ./docs
# 本地预览. 默认地址: http://localhost:3000
docsify serve docs
# 全局安装 apidoc 文档工具,可以根据代码注释,生成API文档
npm install -g apidoc
# 扫描 server/handler 目录中的代码注释,在 docs/apidoc 目录生成API文档
apidoc -i server/handler -o docs/apidoc
# 配置文件 apidoc.json
# 默认地址: http://localhost:3000/apidoc/index.html