Zinx 框架的学习

开始学习 Go 语言实现的 zinx 框架,项目地址为:https://github.com/chaggle/zinx-study

使用 go mod 管理, 初始化为 go mod init github.com/chaggle/zinx-study
并部署代码到 github.com 以及使用 go get 同步到本地 Gopath 的 github 包下!

V0.1 基础的 server 模块

方法

初始化服务器 – NewServer(name string) ziface.IServer

启动服务器 – Start()

停止服务器 – Stop()

运行服务器 – Serve()

属性

名称 – name

IP 版本 – IPVersion

监听 IP – IP

监听端口 – Port

V0.2 简单的链接封装和业务绑定

方法

启动链接 – Start()

停止链接 – Stop()

获取当前链接的 conn 对象 (套接字) – GetTCPConnection() *net.TCPConn

得到链接 ID – GetConnID() uint32

得到客户端连接的地址和端口 – RemoteAddr() net.TCPAddr

发送数据的方法 – Send(data []byte) error

属性
socket TCP 套接字 – Conn *net.TCPConn

链接的 ID – ConnID uint32

当前链接状态 (是否已经关闭) – isClosed bool

与当前链接所绑定的处理业务与方法 – handlerAPI ziface.HandleFunc

等待退出的 channel 管道 – ExitChan chan bool

V0.3 基础的 router 模块

Request 请求封装

将链接与数据绑定一起

属性
链接的句柄 – GetConnection() IConnection

请求数据 – GetData() []byte

方法
得到链接– func (r *Request) GetConnection() ziface.IConnection

得到数据 – func (r *Request) GetData() []byte

新建一个 Request 请求

Router 模块

抽象的 IRouter

处理业务之前的方法 PreHandle(request IRequest) //处理 conn 业务之前的方法

处理业务的主方法 Handle(request IRequest) //处理 conn 业务的主方法

处理业务之后的方法 PostHandle(request IRequest) //处理 conn 业务之后的方法

具体的 BaseRouter

处理业务之前的方法 func (br *BaseRouter) PreHandle(request ziface.IRequest)

处理业务的主方法 func (br *BaseRouter) Handle(request ziface.IRequest)

处理业务之后的方法 func (br *BaseRouter) PostHandle(request ziface.IRequest)

zinx 集成 Router 模块

IServer 增添路由功能 - AddRouter(router IRouter)

Server 类增加 Router 成员 —> 去掉之前的 HandAPI

Connection 类绑定一个 Router 成员

在 Connection 调用已经注册过的 Router 处理业务

使用 zinxV0.3 版本开发服务器

1、创建一个服务器句柄

2、给当前的 zinx 框架加一个自定义的业务路由

3、启动 server

4、需要继承 BaseRouter 去实现三个接口的方法

当前版本只有一个路由能使用,目前只能使用一个路由模块,在加入路由模块会使上一个路由模块方法进行重写覆盖。

V0.4 全局配置模块

路径 :服务器项目主地址/conf/zinx.json (用户进行填写)

创建一个 zinx 的全局配置模块 utils/globalobj.go

初始化后读取用户配置的 zinx.json —> globalobj 对象中对应的 zinx 服务器句柄代码进行参数替换

提供一个 GlobalObject 对象 — var GlobalObject *GlobalObj

使用 zinx0.4 版本进行开发

V0.5 消息封装

定义消息的结构 Message

属性
消息的 ID

消息的长度

消息的内容

方法
SetMsgId(uint32) //设置消息 ID

SetData([]byte) //设置消息内容

SetDataLen(uint32) //设置消息长度

GetDataLen() uint32 //获取消息长度

GetMsgId() uint32 //获取消息 ID

GetData() []byte //获取消息内容

定义解决 TCP 粘包问题的封包拆包的模块

针对 Message 进行 TLV 格式的封装 – func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error)

写 Message 的长度

写 Message 的 ID

写 Message 的内容

针对 Message 进行 TLV 格式的拆包 – func (dp *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error)

先读取固定长度的 head —> 消息的长度和消息的类型

再根据消息内容的长度,再进行一次读写,从 conn 中读取消息的内容

将消息封装机制集成到 Zinx 框架中

将 Message 添加到 Request 属性字段

修改连接读取数据的机制,将之前的单纯读取 byte 改成拆包形式,读取按照 TLV 形式进行读取

给链接提供一个发包的机制:将发送的消息打包,再发送

使用 zinxV0.5 开发

V0.6 多路由模式

消息管理模块(支持多路由 API 调度管理)

属性

集合 - 消息 ID 与对应 router 的关系 - map Apis map[uint32]ziface.IRouter

方法

根据 MsgId 来索引调度路由方法 func (mh *MsgHandle) DoMsgHandler(request ziface.IRequest)

添加路由方法到 map 集合中 func (mh *MsgHandle) AddRouter(msgID uint32, router ziface.IRouter)

消息管理模块集成到 Zinx 框架中

将 server 模块里面的 Router 属性变为 MsgHandle 属性

将 server 模块中的 AddRouter 修改调用 MsgHandler 的 AddRouter

将 connection 模块中的 Router 属性替换为 MsgHandle 属性

将 connection 模块中的 Router 业务调度 Router 的业务改为调度 MsgHandle 调度, 并修改 StartRead 方法

使用 Zinx V0.6 版本开发

V0.7 读写协程分离(小修改,新增一个 goroutine 即可)

1、添加一个 Reader 和 Writer 之间通信的 channel

2、添加一个 Writer Goroutine

3、Reader 由之前发送给客户端 改成 发送给 通信 Channel

4、启动 Reader 和 Writer 一同工作

V0.8 消息队列以及多任务

消息队列以及 Worker 工作池的实现

创建一个消息队列 --- MsgHandler 消息管理模块
	  消息队列 TaskQueue []chan ziface.IRequest
	  工作池的数量 WorkPoolSize uint32
创建多任务work工作池,并且启动

​	  创建一个 worker 工作池 :func (mh *MsgHandle) StartWorkerPool() 
​	  根据 WorkPoolSize 的数量去创建 Worker 
  每个 worker 都应该用一个 Go 去承载
​	  1、阻塞等待当前 worker 的对应的 channel 的消息
​	  2、一旦有消息到来, worker 应该处理当前消息对应的业务
​	  3、将之前的发送消息,全部改成将消息发送给消息队列和 worker 工作池处理

定义一个方法,将消息发送给消息队列工作池的方法
	   func (mh *MsgHandle) SendMsgToTaskQueue(request ziface.IRequest)

将消息队列机制集成到 Zinx 框架中: 
	1、开启并调用消息队列及 worker 工作池, 保证 workerPool 只有一个,应该在创建 Server模块时候开启(在Server listen 之前添加)
	2、将从客户端处理的消息,发送给当前的Worker 工作池来处理,在处理完拆包,得到了 request 请求,交给工作池来处理

使用 Zinx V0.8 版本开发

小型项目,具体以技术方案跟思考为主,而与需求、产品、测试、运维的沟通可以让步于项目的上线


Zinx 框架的学习
https://chaggle.github.io/2022/01/10/go/zinx/zinx/
作者
chaggle
发布于
2022年1月10日
更新于
2025年3月13日
许可协议