Zinx 框架开发笔记

  • Zinx 框架开发笔记
    • Zinx - V0.1 构建最基础的 server
    • Zinx - V0.2 连接封装与业务绑定
    • Zinx - V0.3 框架路由模块
    • Zinx - V0.4 全局配置
    • Zinx - V0.5 消息封装
    • Zinx - V0.6 多路由模式
    • Zinx - V0.7 读写协程分离
    • Zinx - V0.8 消息队列及多任务机制
    • Zinx - V0.9 连接管理
    • Zinx - V1.0 连接属性配置

Golang 快速入门:

  • 【Golang 快速入门】基础语法 + 面向对象
  • 【Golang 快速入门】高级语法:反射 + 并发
  • 【Golang 快速入门】项目实战:即时通信系统
  • 【Golang 快速入门】Go Modules + 生态拓展
  • 【Go 框架开发】Zinx 框架开发笔记

文档:Golang 轻量级并发服务器框架 Zinx

视频:Zinx Golang 轻量级 TCP 服务器框架

本项目所有版本代码都在:https://gitee.com/szluyu99/my-zinx/tree/master/(不同分支对应不同版本)

本文章没有详细代码,只有疏理的思维导图,代码可以参考 Gitee 或文档。

Zinx 框架开发笔记

Zinx:轻量级的 TCP 服务器框架

  • 基础的 Server
  • 简单的连接封装和业务绑定
  • 基础 Router 模块
  • 全局配置
  • 消息封装
  • 多路由模式
  • 读写协程分离
  • 消息队列及多任务
  • 连接管理
  • 连接 属性配置
  • 基于 Zinx 的应用案例

Zinx 架构

参考:初识 Zinx 框架

Zinx - V0.1 构建最基础的 server

1. Zinx-V0.1 基础 Server

Zinx 的最基本的两个模块 zifaceznet

  • ziface 主要是存放一些 Zinx 框架的全部模块的抽象层接口类。

    Zinx 框架的最基本的服务类接口 iserver,定义在该模块中。

  • znet 模块是 Zinx 框架中网络相关功能的实现,所有网络相关模块定义在这里。

#mermaid-svg-DIhKflG4r0fzlhbM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .error-icon{fill:#552222;}#mermaid-svg-DIhKflG4r0fzlhbM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DIhKflG4r0fzlhbM .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-DIhKflG4r0fzlhbM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DIhKflG4r0fzlhbM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DIhKflG4r0fzlhbM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DIhKflG4r0fzlhbM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DIhKflG4r0fzlhbM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DIhKflG4r0fzlhbM .marker.cross{stroke:#333333;}#mermaid-svg-DIhKflG4r0fzlhbM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DIhKflG4r0fzlhbM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .cluster-label text{fill:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .cluster-label span{color:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .label text,#mermaid-svg-DIhKflG4r0fzlhbM span{fill:#333;color:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .node rect,#mermaid-svg-DIhKflG4r0fzlhbM .node circle,#mermaid-svg-DIhKflG4r0fzlhbM .node ellipse,#mermaid-svg-DIhKflG4r0fzlhbM .node polygon,#mermaid-svg-DIhKflG4r0fzlhbM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DIhKflG4r0fzlhbM .node .label{text-align:center;}#mermaid-svg-DIhKflG4r0fzlhbM .node.clickable{cursor:pointer;}#mermaid-svg-DIhKflG4r0fzlhbM .arrowheadPath{fill:#333333;}#mermaid-svg-DIhKflG4r0fzlhbM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DIhKflG4r0fzlhbM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DIhKflG4r0fzlhbM .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-DIhKflG4r0fzlhbM .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-DIhKflG4r0fzlhbM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DIhKflG4r0fzlhbM .cluster text{fill:#333;}#mermaid-svg-DIhKflG4r0fzlhbM .cluster span{color:#333;}#mermaid-svg-DIhKflG4r0fzlhbM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DIhKflG4r0fzlhbM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

基础的 server
方法
属性
启动服务器 - Start()
停止服务器 - Stop()
运行服务器 - Serve()
初始化服务
NewServer(name string) ziface.IServer
名称 - Name string
IP版本 - IPVersion string
监听的IP - IP string
监听的端口 - Port int
  • 启动服务器:基本的服务器开发

    1. 创建一个 TCP 的 Addr
    2. 监听服务器地址,创建 Listener
    3. 阻塞等待连接,进行业务处理
  • 停止服务器:做一些资源、状态、连接信息的回收操作
  • 运行服务器:调用 Start() 方法,调用后做阻塞,以后可以做功能的拓展

V0.1 版本代码:这个版本的代码忘了上传了,可以看参考文档里作者放出来的。

Zinx - V0.2 连接封装与业务绑定

2. Zinx-V0.2 简单的连接封装与业务绑定

#mermaid-svg-mnQDbylAUpUJwYwD {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .error-icon{fill:#552222;}#mermaid-svg-mnQDbylAUpUJwYwD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mnQDbylAUpUJwYwD .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-mnQDbylAUpUJwYwD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mnQDbylAUpUJwYwD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mnQDbylAUpUJwYwD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mnQDbylAUpUJwYwD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mnQDbylAUpUJwYwD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mnQDbylAUpUJwYwD .marker.cross{stroke:#333333;}#mermaid-svg-mnQDbylAUpUJwYwD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mnQDbylAUpUJwYwD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .cluster-label text{fill:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .cluster-label span{color:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .label text,#mermaid-svg-mnQDbylAUpUJwYwD span{fill:#333;color:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .node rect,#mermaid-svg-mnQDbylAUpUJwYwD .node circle,#mermaid-svg-mnQDbylAUpUJwYwD .node ellipse,#mermaid-svg-mnQDbylAUpUJwYwD .node polygon,#mermaid-svg-mnQDbylAUpUJwYwD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mnQDbylAUpUJwYwD .node .label{text-align:center;}#mermaid-svg-mnQDbylAUpUJwYwD .node.clickable{cursor:pointer;}#mermaid-svg-mnQDbylAUpUJwYwD .arrowheadPath{fill:#333333;}#mermaid-svg-mnQDbylAUpUJwYwD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mnQDbylAUpUJwYwD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mnQDbylAUpUJwYwD .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-mnQDbylAUpUJwYwD .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-mnQDbylAUpUJwYwD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mnQDbylAUpUJwYwD .cluster text{fill:#333;}#mermaid-svg-mnQDbylAUpUJwYwD .cluster span{color:#333;}#mermaid-svg-mnQDbylAUpUJwYwD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mnQDbylAUpUJwYwD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

连接 connection
方法
属性
启动连接 - Start()
停止连接 - Stop()
获取连接对象
GetTCPConnection() *net.TCPConn
获取连接ID - GetConnID() uint32
获取客户端的连接地址 - RemoteAddr() net.Addr
发送数据 - Send(data []byte) error
连接绑定的统一处理业务的函数类型
type HandleFunc func(*net.TCPConn, []byte, int) error
socket TCP 套接字 - Conn *net.TCPConn
连接ID - ConnID uint32
连接状态(是否已经关闭) - isClosed bool
与连接绑定的业务方法
handleAPI ziface.HandleFunc
等待连接被动退出的管道 - ExitChan chan bool

V0.2 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.2/(选择 V0.2 分支)

Zinx - V0.3 框架路由模块

参考文档:Zinx 框架基础路由模块

3.1 IRequest 消息请求抽象类

#mermaid-svg-oE1fkBWgq8tW5mzX {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .error-icon{fill:#552222;}#mermaid-svg-oE1fkBWgq8tW5mzX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oE1fkBWgq8tW5mzX .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-oE1fkBWgq8tW5mzX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oE1fkBWgq8tW5mzX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oE1fkBWgq8tW5mzX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oE1fkBWgq8tW5mzX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oE1fkBWgq8tW5mzX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oE1fkBWgq8tW5mzX .marker.cross{stroke:#333333;}#mermaid-svg-oE1fkBWgq8tW5mzX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oE1fkBWgq8tW5mzX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .cluster-label text{fill:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .cluster-label span{color:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .label text,#mermaid-svg-oE1fkBWgq8tW5mzX span{fill:#333;color:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .node rect,#mermaid-svg-oE1fkBWgq8tW5mzX .node circle,#mermaid-svg-oE1fkBWgq8tW5mzX .node ellipse,#mermaid-svg-oE1fkBWgq8tW5mzX .node polygon,#mermaid-svg-oE1fkBWgq8tW5mzX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oE1fkBWgq8tW5mzX .node .label{text-align:center;}#mermaid-svg-oE1fkBWgq8tW5mzX .node.clickable{cursor:pointer;}#mermaid-svg-oE1fkBWgq8tW5mzX .arrowheadPath{fill:#333333;}#mermaid-svg-oE1fkBWgq8tW5mzX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oE1fkBWgq8tW5mzX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oE1fkBWgq8tW5mzX .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-oE1fkBWgq8tW5mzX .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-oE1fkBWgq8tW5mzX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oE1fkBWgq8tW5mzX .cluster text{fill:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX .cluster span{color:#333;}#mermaid-svg-oE1fkBWgq8tW5mzX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oE1fkBWgq8tW5mzX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Request 请求封装
将连接和数据绑定在一起
属性
和客户端建立好的连接 - conn ziface.IConnection
客户端请求的数据 - data []byte
方法
得到当前连接 - GetConnection() IConnection
得到当前数据 - GetData() []byte

3.2 IRouter 路由配置抽象类

#mermaid-svg-zZGpT3S1qbolmomp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zZGpT3S1qbolmomp .error-icon{fill:#552222;}#mermaid-svg-zZGpT3S1qbolmomp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zZGpT3S1qbolmomp .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-zZGpT3S1qbolmomp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zZGpT3S1qbolmomp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zZGpT3S1qbolmomp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zZGpT3S1qbolmomp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zZGpT3S1qbolmomp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zZGpT3S1qbolmomp .marker.cross{stroke:#333333;}#mermaid-svg-zZGpT3S1qbolmomp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zZGpT3S1qbolmomp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zZGpT3S1qbolmomp .cluster-label text{fill:#333;}#mermaid-svg-zZGpT3S1qbolmomp .cluster-label span{color:#333;}#mermaid-svg-zZGpT3S1qbolmomp .label text,#mermaid-svg-zZGpT3S1qbolmomp span{fill:#333;color:#333;}#mermaid-svg-zZGpT3S1qbolmomp .node rect,#mermaid-svg-zZGpT3S1qbolmomp .node circle,#mermaid-svg-zZGpT3S1qbolmomp .node ellipse,#mermaid-svg-zZGpT3S1qbolmomp .node polygon,#mermaid-svg-zZGpT3S1qbolmomp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zZGpT3S1qbolmomp .node .label{text-align:center;}#mermaid-svg-zZGpT3S1qbolmomp .node.clickable{cursor:pointer;}#mermaid-svg-zZGpT3S1qbolmomp .arrowheadPath{fill:#333333;}#mermaid-svg-zZGpT3S1qbolmomp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zZGpT3S1qbolmomp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zZGpT3S1qbolmomp .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-zZGpT3S1qbolmomp .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-zZGpT3S1qbolmomp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zZGpT3S1qbolmomp .cluster text{fill:#333;}#mermaid-svg-zZGpT3S1qbolmomp .cluster span{color:#333;}#mermaid-svg-zZGpT3S1qbolmomp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zZGpT3S1qbolmomp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Router 模块
抽象的 IRouter
处理 conn 业务之前的方法 - PreHandle(request IRequest)
处理 conn 业务的主方法 - Handle(request IRequest)
处理 conn 业务之后的方法 - PostHandle(request IRequest)
具体的 BaseRouter
处理 conn 业务之前的方法
func (b *BaseRouter) PreHandle(request ziface.IRequest) {}
处理 conn 业务的主方法
func (b *BaseRouter) Handle(request ziface.IRequest) {}
处理 conn 业务之后的方法
func (b *BaseRouter) PostHandle(request ziface.IRequest) {}

3.3 Zinx-V0.3 集成简单路由功能

#mermaid-svg-ZsD2xBwGPwQXoLht {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .error-icon{fill:#552222;}#mermaid-svg-ZsD2xBwGPwQXoLht .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZsD2xBwGPwQXoLht .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ZsD2xBwGPwQXoLht .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZsD2xBwGPwQXoLht .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZsD2xBwGPwQXoLht .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZsD2xBwGPwQXoLht .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZsD2xBwGPwQXoLht .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZsD2xBwGPwQXoLht .marker.cross{stroke:#333333;}#mermaid-svg-ZsD2xBwGPwQXoLht svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZsD2xBwGPwQXoLht .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .cluster-label text{fill:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .cluster-label span{color:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .label text,#mermaid-svg-ZsD2xBwGPwQXoLht span{fill:#333;color:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .node rect,#mermaid-svg-ZsD2xBwGPwQXoLht .node circle,#mermaid-svg-ZsD2xBwGPwQXoLht .node ellipse,#mermaid-svg-ZsD2xBwGPwQXoLht .node polygon,#mermaid-svg-ZsD2xBwGPwQXoLht .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZsD2xBwGPwQXoLht .node .label{text-align:center;}#mermaid-svg-ZsD2xBwGPwQXoLht .node.clickable{cursor:pointer;}#mermaid-svg-ZsD2xBwGPwQXoLht .arrowheadPath{fill:#333333;}#mermaid-svg-ZsD2xBwGPwQXoLht .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZsD2xBwGPwQXoLht .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZsD2xBwGPwQXoLht .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-ZsD2xBwGPwQXoLht .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-ZsD2xBwGPwQXoLht .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZsD2xBwGPwQXoLht .cluster text{fill:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht .cluster span{color:#333;}#mermaid-svg-ZsD2xBwGPwQXoLht div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZsD2xBwGPwQXoLht :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Zinx 集成 router 模块
IServer 增添路由添加功能 - AddRouter(router IRouter)
Server 类增添 Router 成员 - 取代之前的 HandleAPI
Connection 类绑定一个 Router 成员
在 Connection 调用已经注册的 Router 处理业务

3.5 使用 Zinx-V0.3 完成应用程序

#mermaid-svg-kPmz5NYWEjnGbxxE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .error-icon{fill:#552222;}#mermaid-svg-kPmz5NYWEjnGbxxE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kPmz5NYWEjnGbxxE .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-kPmz5NYWEjnGbxxE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kPmz5NYWEjnGbxxE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kPmz5NYWEjnGbxxE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kPmz5NYWEjnGbxxE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kPmz5NYWEjnGbxxE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kPmz5NYWEjnGbxxE .marker.cross{stroke:#333333;}#mermaid-svg-kPmz5NYWEjnGbxxE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kPmz5NYWEjnGbxxE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .cluster-label text{fill:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .cluster-label span{color:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .label text,#mermaid-svg-kPmz5NYWEjnGbxxE span{fill:#333;color:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .node rect,#mermaid-svg-kPmz5NYWEjnGbxxE .node circle,#mermaid-svg-kPmz5NYWEjnGbxxE .node ellipse,#mermaid-svg-kPmz5NYWEjnGbxxE .node polygon,#mermaid-svg-kPmz5NYWEjnGbxxE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kPmz5NYWEjnGbxxE .node .label{text-align:center;}#mermaid-svg-kPmz5NYWEjnGbxxE .node.clickable{cursor:pointer;}#mermaid-svg-kPmz5NYWEjnGbxxE .arrowheadPath{fill:#333333;}#mermaid-svg-kPmz5NYWEjnGbxxE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kPmz5NYWEjnGbxxE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kPmz5NYWEjnGbxxE .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-kPmz5NYWEjnGbxxE .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-kPmz5NYWEjnGbxxE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kPmz5NYWEjnGbxxE .cluster text{fill:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE .cluster span{color:#333;}#mermaid-svg-kPmz5NYWEjnGbxxE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kPmz5NYWEjnGbxxE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

使用 ZinxV0.3开发应用程序
开发步骤
1 创建一个 server 句柄, 使用 Zinx 的 api
2 给当前 zinx 框架添加一个自定义的 router
3 启动 server
自定义的 router 需要继承 BaseRouter,实现 PreHandle、Handle、PostHandle 方法

V0.3 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.3/(选择 V0.3 分支)

Zinx - V0.4 全局配置

四、Zinx 的全局配置

这里使用 JSON 作为配置文件,zinx.json 中的配置信息:

{"Name":"demo server","Host":"127.0.0.1","TcpPort":7777,"MaxConn":3
}
#mermaid-svg-qZhc2qPfCrQvhCI9 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .error-icon{fill:#552222;}#mermaid-svg-qZhc2qPfCrQvhCI9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qZhc2qPfCrQvhCI9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .marker.cross{stroke:#333333;}#mermaid-svg-qZhc2qPfCrQvhCI9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .cluster-label text{fill:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .cluster-label span{color:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .label text,#mermaid-svg-qZhc2qPfCrQvhCI9 span{fill:#333;color:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .node rect,#mermaid-svg-qZhc2qPfCrQvhCI9 .node circle,#mermaid-svg-qZhc2qPfCrQvhCI9 .node ellipse,#mermaid-svg-qZhc2qPfCrQvhCI9 .node polygon,#mermaid-svg-qZhc2qPfCrQvhCI9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .node .label{text-align:center;}#mermaid-svg-qZhc2qPfCrQvhCI9 .node.clickable{cursor:pointer;}#mermaid-svg-qZhc2qPfCrQvhCI9 .arrowheadPath{fill:#333333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-qZhc2qPfCrQvhCI9 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-qZhc2qPfCrQvhCI9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qZhc2qPfCrQvhCI9 .cluster text{fill:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 .cluster span{color:#333;}#mermaid-svg-qZhc2qPfCrQvhCI9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qZhc2qPfCrQvhCI9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Zinx V0.4 全局配置
配置文件 /conf/zinx.json(用户编写)
创建一个 Zinx 全局配置模块 utils/globalobj.go
在 init() 中 读取用户配置的 zinx.json 到 globalObj 对象中
将 Zinx 框架中全部的硬编码,使用 globalObj 中的参数进行替换
使用 Zinx V0.4 开发应用程序

V0.4 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.4/(选择 V0.4 分支)

Zinx - V0.5 消息封装

五、Zinx 的消息封装

定义一个消息的结构 Message:5.1 创建消息封装类型

#mermaid-svg-Brz4uxsUSrgk3KQW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .error-icon{fill:#552222;}#mermaid-svg-Brz4uxsUSrgk3KQW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Brz4uxsUSrgk3KQW .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Brz4uxsUSrgk3KQW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Brz4uxsUSrgk3KQW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Brz4uxsUSrgk3KQW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Brz4uxsUSrgk3KQW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Brz4uxsUSrgk3KQW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Brz4uxsUSrgk3KQW .marker.cross{stroke:#333333;}#mermaid-svg-Brz4uxsUSrgk3KQW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Brz4uxsUSrgk3KQW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .cluster-label text{fill:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .cluster-label span{color:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .label text,#mermaid-svg-Brz4uxsUSrgk3KQW span{fill:#333;color:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .node rect,#mermaid-svg-Brz4uxsUSrgk3KQW .node circle,#mermaid-svg-Brz4uxsUSrgk3KQW .node ellipse,#mermaid-svg-Brz4uxsUSrgk3KQW .node polygon,#mermaid-svg-Brz4uxsUSrgk3KQW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Brz4uxsUSrgk3KQW .node .label{text-align:center;}#mermaid-svg-Brz4uxsUSrgk3KQW .node.clickable{cursor:pointer;}#mermaid-svg-Brz4uxsUSrgk3KQW .arrowheadPath{fill:#333333;}#mermaid-svg-Brz4uxsUSrgk3KQW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Brz4uxsUSrgk3KQW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Brz4uxsUSrgk3KQW .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Brz4uxsUSrgk3KQW .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Brz4uxsUSrgk3KQW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Brz4uxsUSrgk3KQW .cluster text{fill:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW .cluster span{color:#333;}#mermaid-svg-Brz4uxsUSrgk3KQW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Brz4uxsUSrgk3KQW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

消息结构 Message
属性
方法
消息ID - Id uint32
消息长度 - DataLen uint32
消息内容 - []byte
获取消息ID - GetMsgId() uint32
获取消息长度 - GetMsgLen() uint32
获取消息内容 - GetData() []byte
设置消息ID - SetMsgId(uint32)
设置消息长度 - SetData([]byte)
设置消息内容 - SetDataLen(uint32)

使用 TLV (Type-Len-Value) 封包格式解决 TCP 粘包问题:5.2 消息的封包和拆包

由于 Zinx 也是 TCP 流的形式传播数据,难免会出现消息 1 和消息 2 一同发送,那么 Zinx 就需要有能力区分两个消息的边界,所以 Zinx 此时应该提供一个统一的拆包和封包的方法。

  • 封包:在发包之前打包成如上图这种格式的有 head 和 body 的两部分的包
  • 拆包:在收到数据的时候分两次进行读取,先读取固定长度的 head 部分,得到后续 Data 的长度,再根据 DataLen 读取之后的 body。
#mermaid-svg-e6VigW41dyMYT0Ea {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .error-icon{fill:#552222;}#mermaid-svg-e6VigW41dyMYT0Ea .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e6VigW41dyMYT0Ea .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-e6VigW41dyMYT0Ea .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e6VigW41dyMYT0Ea .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e6VigW41dyMYT0Ea .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e6VigW41dyMYT0Ea .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e6VigW41dyMYT0Ea .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e6VigW41dyMYT0Ea .marker.cross{stroke:#333333;}#mermaid-svg-e6VigW41dyMYT0Ea svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e6VigW41dyMYT0Ea .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .cluster-label text{fill:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .cluster-label span{color:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .label text,#mermaid-svg-e6VigW41dyMYT0Ea span{fill:#333;color:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .node rect,#mermaid-svg-e6VigW41dyMYT0Ea .node circle,#mermaid-svg-e6VigW41dyMYT0Ea .node ellipse,#mermaid-svg-e6VigW41dyMYT0Ea .node polygon,#mermaid-svg-e6VigW41dyMYT0Ea .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-e6VigW41dyMYT0Ea .node .label{text-align:center;}#mermaid-svg-e6VigW41dyMYT0Ea .node.clickable{cursor:pointer;}#mermaid-svg-e6VigW41dyMYT0Ea .arrowheadPath{fill:#333333;}#mermaid-svg-e6VigW41dyMYT0Ea .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-e6VigW41dyMYT0Ea .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-e6VigW41dyMYT0Ea .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-e6VigW41dyMYT0Ea .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-e6VigW41dyMYT0Ea .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-e6VigW41dyMYT0Ea .cluster text{fill:#333;}#mermaid-svg-e6VigW41dyMYT0Ea .cluster span{color:#333;}#mermaid-svg-e6VigW41dyMYT0Ea div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-e6VigW41dyMYT0Ea :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

封包拆包模块
针对 Message 进行 TVL 格式的封装
func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error)
针对 Message 进行 TLV 格式的拆包
func (dp *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error)
写 Message 的长度
写 Message 的 ID
写 Message 的 内容
先读固定长度的 Head:
消息内容的长度、消息的类型
再根据消息内容的长度,
进行一次读写,从 conn 中读取消息内容

测试拆包封包功能:https://gitee.com/szluyu99/my-zinx/blob/V0.5/znet/datapack_test.go

将封包、拆包功能集成到 Zin 中:5.3 Zinx - V0.5 代码实现

#mermaid-svg-hZJlqkHZWcS3vFqS {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .error-icon{fill:#552222;}#mermaid-svg-hZJlqkHZWcS3vFqS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hZJlqkHZWcS3vFqS .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-hZJlqkHZWcS3vFqS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hZJlqkHZWcS3vFqS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hZJlqkHZWcS3vFqS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hZJlqkHZWcS3vFqS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hZJlqkHZWcS3vFqS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hZJlqkHZWcS3vFqS .marker.cross{stroke:#333333;}#mermaid-svg-hZJlqkHZWcS3vFqS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hZJlqkHZWcS3vFqS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .cluster-label text{fill:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .cluster-label span{color:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .label text,#mermaid-svg-hZJlqkHZWcS3vFqS span{fill:#333;color:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .node rect,#mermaid-svg-hZJlqkHZWcS3vFqS .node circle,#mermaid-svg-hZJlqkHZWcS3vFqS .node ellipse,#mermaid-svg-hZJlqkHZWcS3vFqS .node polygon,#mermaid-svg-hZJlqkHZWcS3vFqS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hZJlqkHZWcS3vFqS .node .label{text-align:center;}#mermaid-svg-hZJlqkHZWcS3vFqS .node.clickable{cursor:pointer;}#mermaid-svg-hZJlqkHZWcS3vFqS .arrowheadPath{fill:#333333;}#mermaid-svg-hZJlqkHZWcS3vFqS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hZJlqkHZWcS3vFqS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hZJlqkHZWcS3vFqS .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-hZJlqkHZWcS3vFqS .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-hZJlqkHZWcS3vFqS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hZJlqkHZWcS3vFqS .cluster text{fill:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS .cluster span{color:#333;}#mermaid-svg-hZJlqkHZWcS3vFqS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hZJlqkHZWcS3vFqS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

集成到 Zinx
将 Message 添加到 Request 属性中
修改连接读取数据的机制:
将之前单纯的读取 byte 改成拆包按照 TLV 形式读取
给连接提供一个发包机制:将发送的消息进行打包再,发送

使用 Zinx V0.5 开发应用:5.4 使用 Zinx - V0.5 完成应用程序

V0.5 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.5/(选择 V0.5 分支)

Zinx - V0.6 多路由模式

参考:六、Zinx 的多路由模式

6.1 创建消息管理模块

#mermaid-svg-nbTCE5VtzELmc86t {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nbTCE5VtzELmc86t .error-icon{fill:#552222;}#mermaid-svg-nbTCE5VtzELmc86t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nbTCE5VtzELmc86t .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-nbTCE5VtzELmc86t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nbTCE5VtzELmc86t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nbTCE5VtzELmc86t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nbTCE5VtzELmc86t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nbTCE5VtzELmc86t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nbTCE5VtzELmc86t .marker.cross{stroke:#333333;}#mermaid-svg-nbTCE5VtzELmc86t svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nbTCE5VtzELmc86t .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nbTCE5VtzELmc86t .cluster-label text{fill:#333;}#mermaid-svg-nbTCE5VtzELmc86t .cluster-label span{color:#333;}#mermaid-svg-nbTCE5VtzELmc86t .label text,#mermaid-svg-nbTCE5VtzELmc86t span{fill:#333;color:#333;}#mermaid-svg-nbTCE5VtzELmc86t .node rect,#mermaid-svg-nbTCE5VtzELmc86t .node circle,#mermaid-svg-nbTCE5VtzELmc86t .node ellipse,#mermaid-svg-nbTCE5VtzELmc86t .node polygon,#mermaid-svg-nbTCE5VtzELmc86t .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nbTCE5VtzELmc86t .node .label{text-align:center;}#mermaid-svg-nbTCE5VtzELmc86t .node.clickable{cursor:pointer;}#mermaid-svg-nbTCE5VtzELmc86t .arrowheadPath{fill:#333333;}#mermaid-svg-nbTCE5VtzELmc86t .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nbTCE5VtzELmc86t .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nbTCE5VtzELmc86t .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-nbTCE5VtzELmc86t .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-nbTCE5VtzELmc86t .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nbTCE5VtzELmc86t .cluster text{fill:#333;}#mermaid-svg-nbTCE5VtzELmc86t .cluster span{color:#333;}#mermaid-svg-nbTCE5VtzELmc86t div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nbTCE5VtzELmc86t :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

消息管理模块 MsgHandler
(支持多路由业务API调度管理)
属性
MsgID 和对应的 router
Apis map[uint32]ziface.IRouter
方法
根据 MsgID 来索引调度路由方法
func (mh *MsgHandle) DoMsgHandler(request ziface.IRequest)
添加路由方法到 Apis 集合中
func (mh *MsgHandle) AddRouter(msgID uint32, router ziface.IRouter)

6.2 Zinx - V0.6 代码实现

#mermaid-svg-DbxabjAg39PKiue8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-DbxabjAg39PKiue8 .error-icon{fill:#552222;}#mermaid-svg-DbxabjAg39PKiue8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DbxabjAg39PKiue8 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-DbxabjAg39PKiue8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DbxabjAg39PKiue8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DbxabjAg39PKiue8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DbxabjAg39PKiue8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DbxabjAg39PKiue8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DbxabjAg39PKiue8 .marker.cross{stroke:#333333;}#mermaid-svg-DbxabjAg39PKiue8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DbxabjAg39PKiue8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DbxabjAg39PKiue8 .cluster-label text{fill:#333;}#mermaid-svg-DbxabjAg39PKiue8 .cluster-label span{color:#333;}#mermaid-svg-DbxabjAg39PKiue8 .label text,#mermaid-svg-DbxabjAg39PKiue8 span{fill:#333;color:#333;}#mermaid-svg-DbxabjAg39PKiue8 .node rect,#mermaid-svg-DbxabjAg39PKiue8 .node circle,#mermaid-svg-DbxabjAg39PKiue8 .node ellipse,#mermaid-svg-DbxabjAg39PKiue8 .node polygon,#mermaid-svg-DbxabjAg39PKiue8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DbxabjAg39PKiue8 .node .label{text-align:center;}#mermaid-svg-DbxabjAg39PKiue8 .node.clickable{cursor:pointer;}#mermaid-svg-DbxabjAg39PKiue8 .arrowheadPath{fill:#333333;}#mermaid-svg-DbxabjAg39PKiue8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DbxabjAg39PKiue8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DbxabjAg39PKiue8 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-DbxabjAg39PKiue8 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-DbxabjAg39PKiue8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DbxabjAg39PKiue8 .cluster text{fill:#333;}#mermaid-svg-DbxabjAg39PKiue8 .cluster span{color:#333;}#mermaid-svg-DbxabjAg39PKiue8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DbxabjAg39PKiue8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

消息管理模块集成到 Zinx
1 将 server 模块的 Router 属性成 MsgHandler
2 将 server 模块的 AddRouter 修改为调用 MsgHandler 的 AddRouter
AddRouter(msgID uint32, router IRouter)
3 将 connection 模块的 Router 属性替换成 MsgHandler
修改初始化方法
4 将 connection 模块调度 Router 的业务替换成 MsgHandler 调度
修改 StartRouter 方法

V0.6 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.6/(选择 V0.6 分支)

Zinx - V0.7 读写协程分离

参考:七、Zinx的读写分离模型

#mermaid-svg-l9jHZeLXxjkbi3Ip {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .error-icon{fill:#552222;}#mermaid-svg-l9jHZeLXxjkbi3Ip .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-l9jHZeLXxjkbi3Ip .marker{fill:#333333;stroke:#333333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .marker.cross{stroke:#333333;}#mermaid-svg-l9jHZeLXxjkbi3Ip svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .cluster-label text{fill:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .cluster-label span{color:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .label text,#mermaid-svg-l9jHZeLXxjkbi3Ip span{fill:#333;color:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .node rect,#mermaid-svg-l9jHZeLXxjkbi3Ip .node circle,#mermaid-svg-l9jHZeLXxjkbi3Ip .node ellipse,#mermaid-svg-l9jHZeLXxjkbi3Ip .node polygon,#mermaid-svg-l9jHZeLXxjkbi3Ip .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .node .label{text-align:center;}#mermaid-svg-l9jHZeLXxjkbi3Ip .node.clickable{cursor:pointer;}#mermaid-svg-l9jHZeLXxjkbi3Ip .arrowheadPath{fill:#333333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-l9jHZeLXxjkbi3Ip .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-l9jHZeLXxjkbi3Ip .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-l9jHZeLXxjkbi3Ip .cluster text{fill:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip .cluster span{color:#333;}#mermaid-svg-l9jHZeLXxjkbi3Ip div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-l9jHZeLXxjkbi3Ip :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

读写协程分离
1 添加一个 Reader 和 Writer 之间通信的 channel
2 添加一个 Writer Goroutine
3 Reader 由之前直接发送给客户端改成
发送给通信 channel
4 启动 Reader 和 Writer 一同工作

7.2 使用 Zinx-V0.7 完成应用程序

V0.7 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.7/(选择 V0.7 分支)

Zinx - V0.8 消息队列及多任务机制

参考:八、Zinx 的消息队列及多任务机制

设计架构:

消息队列及多任务:

  1. 8.1 创建消息队列
#mermaid-svg-9vduNKoA4sX0uxK3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .error-icon{fill:#552222;}#mermaid-svg-9vduNKoA4sX0uxK3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9vduNKoA4sX0uxK3 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-9vduNKoA4sX0uxK3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9vduNKoA4sX0uxK3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9vduNKoA4sX0uxK3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9vduNKoA4sX0uxK3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9vduNKoA4sX0uxK3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9vduNKoA4sX0uxK3 .marker.cross{stroke:#333333;}#mermaid-svg-9vduNKoA4sX0uxK3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9vduNKoA4sX0uxK3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .cluster-label text{fill:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .cluster-label span{color:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .label text,#mermaid-svg-9vduNKoA4sX0uxK3 span{fill:#333;color:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .node rect,#mermaid-svg-9vduNKoA4sX0uxK3 .node circle,#mermaid-svg-9vduNKoA4sX0uxK3 .node ellipse,#mermaid-svg-9vduNKoA4sX0uxK3 .node polygon,#mermaid-svg-9vduNKoA4sX0uxK3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9vduNKoA4sX0uxK3 .node .label{text-align:center;}#mermaid-svg-9vduNKoA4sX0uxK3 .node.clickable{cursor:pointer;}#mermaid-svg-9vduNKoA4sX0uxK3 .arrowheadPath{fill:#333333;}#mermaid-svg-9vduNKoA4sX0uxK3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9vduNKoA4sX0uxK3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9vduNKoA4sX0uxK3 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-9vduNKoA4sX0uxK3 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-9vduNKoA4sX0uxK3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9vduNKoA4sX0uxK3 .cluster text{fill:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 .cluster span{color:#333;}#mermaid-svg-9vduNKoA4sX0uxK3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9vduNKoA4sX0uxK3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

增加属性
增加属性
1 创建一个消息队列
MsgHandler 消息管理模块中
消息队列 - TaskQueue []chan ziface.IRequest
worker 工作池的数量 - WorkerPoolSize uint32
在全局配置中获取,也可以让用户在配置文件设置
  1. 8.2 创建及启动 Worker 工作池
#mermaid-svg-EFyzIkkw4KvHQBDL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .error-icon{fill:#552222;}#mermaid-svg-EFyzIkkw4KvHQBDL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EFyzIkkw4KvHQBDL .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-EFyzIkkw4KvHQBDL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EFyzIkkw4KvHQBDL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EFyzIkkw4KvHQBDL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EFyzIkkw4KvHQBDL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EFyzIkkw4KvHQBDL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EFyzIkkw4KvHQBDL .marker.cross{stroke:#333333;}#mermaid-svg-EFyzIkkw4KvHQBDL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EFyzIkkw4KvHQBDL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .cluster-label text{fill:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .cluster-label span{color:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .label text,#mermaid-svg-EFyzIkkw4KvHQBDL span{fill:#333;color:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .node rect,#mermaid-svg-EFyzIkkw4KvHQBDL .node circle,#mermaid-svg-EFyzIkkw4KvHQBDL .node ellipse,#mermaid-svg-EFyzIkkw4KvHQBDL .node polygon,#mermaid-svg-EFyzIkkw4KvHQBDL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EFyzIkkw4KvHQBDL .node .label{text-align:center;}#mermaid-svg-EFyzIkkw4KvHQBDL .node.clickable{cursor:pointer;}#mermaid-svg-EFyzIkkw4KvHQBDL .arrowheadPath{fill:#333333;}#mermaid-svg-EFyzIkkw4KvHQBDL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EFyzIkkw4KvHQBDL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EFyzIkkw4KvHQBDL .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-EFyzIkkw4KvHQBDL .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-EFyzIkkw4KvHQBDL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EFyzIkkw4KvHQBDL .cluster text{fill:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL .cluster span{color:#333;}#mermaid-svg-EFyzIkkw4KvHQBDL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EFyzIkkw4KvHQBDL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

2 创建多任务 worker 的工作池并且启动
创建一个 worker 的工作池
func (mh *MsgHandle) StartWorkerPool()
1 根据 workerPoolSize 的数量去创建 worker
func (mh *MsgHandle) StartOneWorker(workerID int, taskQueue chan ziface.IRequest)
2 每个 worker 应该用一个 goroutinie 去承载
阻塞的等待与当前 worker 对应的 channel 的消息
一旦有消息,worker 处理当前消息对应的业务,调用 DoMessage()
  1. 将之前的发送消息,全部改成:把消息发送给 消息队列 和 worker 工作池来处理 8.3 发送消息给消息队列
#mermaid-svg-oMS3TlzHapxPHbEK {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .error-icon{fill:#552222;}#mermaid-svg-oMS3TlzHapxPHbEK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oMS3TlzHapxPHbEK .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-oMS3TlzHapxPHbEK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oMS3TlzHapxPHbEK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oMS3TlzHapxPHbEK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oMS3TlzHapxPHbEK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oMS3TlzHapxPHbEK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oMS3TlzHapxPHbEK .marker.cross{stroke:#333333;}#mermaid-svg-oMS3TlzHapxPHbEK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oMS3TlzHapxPHbEK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .cluster-label text{fill:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .cluster-label span{color:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .label text,#mermaid-svg-oMS3TlzHapxPHbEK span{fill:#333;color:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .node rect,#mermaid-svg-oMS3TlzHapxPHbEK .node circle,#mermaid-svg-oMS3TlzHapxPHbEK .node ellipse,#mermaid-svg-oMS3TlzHapxPHbEK .node polygon,#mermaid-svg-oMS3TlzHapxPHbEK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oMS3TlzHapxPHbEK .node .label{text-align:center;}#mermaid-svg-oMS3TlzHapxPHbEK .node.clickable{cursor:pointer;}#mermaid-svg-oMS3TlzHapxPHbEK .arrowheadPath{fill:#333333;}#mermaid-svg-oMS3TlzHapxPHbEK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oMS3TlzHapxPHbEK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oMS3TlzHapxPHbEK .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-oMS3TlzHapxPHbEK .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-oMS3TlzHapxPHbEK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oMS3TlzHapxPHbEK .cluster text{fill:#333;}#mermaid-svg-oMS3TlzHapxPHbEK .cluster span{color:#333;}#mermaid-svg-oMS3TlzHapxPHbEK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oMS3TlzHapxPHbEK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

3 定义一个方法,将消息发送给消息队列工作池
func (mh *MsgHandle) SendMsgToTaskQueue(request ziface.IRequest)
1 保证每个 worker 收到 request 任务均衡(平均分配),
让哪个 worker 去处理,只需要将 request 发给对应的 taskQueue 即可
2 将消息直接发送给对应 channel

将消息队列集成到 Zinx 框架:8.4 Zinx-V0.8 代码实现

#mermaid-svg-JZRR2ZnwvUAHNcI2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .error-icon{fill:#552222;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .marker.cross{stroke:#333333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .cluster-label text{fill:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .cluster-label span{color:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .label text,#mermaid-svg-JZRR2ZnwvUAHNcI2 span{fill:#333;color:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .node rect,#mermaid-svg-JZRR2ZnwvUAHNcI2 .node circle,#mermaid-svg-JZRR2ZnwvUAHNcI2 .node ellipse,#mermaid-svg-JZRR2ZnwvUAHNcI2 .node polygon,#mermaid-svg-JZRR2ZnwvUAHNcI2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .node .label{text-align:center;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .node.clickable{cursor:pointer;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .arrowheadPath{fill:#333333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .cluster text{fill:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 .cluster span{color:#333;}#mermaid-svg-JZRR2ZnwvUAHNcI2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JZRR2ZnwvUAHNcI2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Zinx V0.8
1 开启并调用消息队列及 worker 工作池
(在 server listen 之前开启)
2 将从客户端处理的消息,发送给当前的 worker 工作池来处理
(在已经处理完拆包,得到 request 请求,交给工作池处理)

8.5 使用 Zinx-V0.8 完成应用程序

配置文件新增 WorkerPoolSize 为 10

{"Name": "Zinx V0.8 demoServerApp","Host": "127.0.0.1","TcpPort": 8999,"MaxConn": 3,"WorkerPoolSize": 10
}

V0.8 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.8/(选择 V0.8 分支)

Zinx - V0.9 连接管理

九、Zinx 的连接管理

#mermaid-svg-qHuT2wG5HWN46lSH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .error-icon{fill:#552222;}#mermaid-svg-qHuT2wG5HWN46lSH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qHuT2wG5HWN46lSH .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qHuT2wG5HWN46lSH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qHuT2wG5HWN46lSH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qHuT2wG5HWN46lSH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qHuT2wG5HWN46lSH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qHuT2wG5HWN46lSH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qHuT2wG5HWN46lSH .marker.cross{stroke:#333333;}#mermaid-svg-qHuT2wG5HWN46lSH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qHuT2wG5HWN46lSH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .cluster-label text{fill:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .cluster-label span{color:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .label text,#mermaid-svg-qHuT2wG5HWN46lSH span{fill:#333;color:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .node rect,#mermaid-svg-qHuT2wG5HWN46lSH .node circle,#mermaid-svg-qHuT2wG5HWN46lSH .node ellipse,#mermaid-svg-qHuT2wG5HWN46lSH .node polygon,#mermaid-svg-qHuT2wG5HWN46lSH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qHuT2wG5HWN46lSH .node .label{text-align:center;}#mermaid-svg-qHuT2wG5HWN46lSH .node.clickable{cursor:pointer;}#mermaid-svg-qHuT2wG5HWN46lSH .arrowheadPath{fill:#333333;}#mermaid-svg-qHuT2wG5HWN46lSH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qHuT2wG5HWN46lSH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qHuT2wG5HWN46lSH .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-qHuT2wG5HWN46lSH .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-qHuT2wG5HWN46lSH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qHuT2wG5HWN46lSH .cluster text{fill:#333;}#mermaid-svg-qHuT2wG5HWN46lSH .cluster span{color:#333;}#mermaid-svg-qHuT2wG5HWN46lSH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qHuT2wG5HWN46lSH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Zinx V0.9 连接管理
创建一个连接管理模块(定义、属性、方法)--- ConnManager
将连接管理模块集成到 Zinx 框架中
给 Zinx 框架提供 创建连接之后 / 销毁连接之前 要处理的业务
提供给用户能够注册 Hook 函数
使用 Zinx V0.9 进行开发应用程序

9.1 创建连接管理模块:ConnManager

#mermaid-svg-pmA0nYMG67pcFUhy {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .error-icon{fill:#552222;}#mermaid-svg-pmA0nYMG67pcFUhy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pmA0nYMG67pcFUhy .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-pmA0nYMG67pcFUhy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pmA0nYMG67pcFUhy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pmA0nYMG67pcFUhy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pmA0nYMG67pcFUhy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pmA0nYMG67pcFUhy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pmA0nYMG67pcFUhy .marker.cross{stroke:#333333;}#mermaid-svg-pmA0nYMG67pcFUhy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pmA0nYMG67pcFUhy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .cluster-label text{fill:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .cluster-label span{color:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .label text,#mermaid-svg-pmA0nYMG67pcFUhy span{fill:#333;color:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .node rect,#mermaid-svg-pmA0nYMG67pcFUhy .node circle,#mermaid-svg-pmA0nYMG67pcFUhy .node ellipse,#mermaid-svg-pmA0nYMG67pcFUhy .node polygon,#mermaid-svg-pmA0nYMG67pcFUhy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pmA0nYMG67pcFUhy .node .label{text-align:center;}#mermaid-svg-pmA0nYMG67pcFUhy .node.clickable{cursor:pointer;}#mermaid-svg-pmA0nYMG67pcFUhy .arrowheadPath{fill:#333333;}#mermaid-svg-pmA0nYMG67pcFUhy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pmA0nYMG67pcFUhy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pmA0nYMG67pcFUhy .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-pmA0nYMG67pcFUhy .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-pmA0nYMG67pcFUhy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pmA0nYMG67pcFUhy .cluster text{fill:#333;}#mermaid-svg-pmA0nYMG67pcFUhy .cluster span{color:#333;}#mermaid-svg-pmA0nYMG67pcFUhy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pmA0nYMG67pcFUhy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

ConnManager
属性
已经创建的连接集合
connections map[uint32]ziface.IConnection
针对 map 的互斥锁
connLock sync.RWMutex
方法
添加连接
Add(conn IConnection)
删除连接
Remove(conn IConnection)
根据连接 ID 查找对应的连接
Get(connID uint32) (IConnection, error)
总连接个数
Len() int
清理全部的连接
ClearConn()

9.2 连接管理模块集成到 Zinx 中

#mermaid-svg-2TGJKoqjQUZC7UKr {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .error-icon{fill:#552222;}#mermaid-svg-2TGJKoqjQUZC7UKr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2TGJKoqjQUZC7UKr .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-2TGJKoqjQUZC7UKr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2TGJKoqjQUZC7UKr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2TGJKoqjQUZC7UKr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2TGJKoqjQUZC7UKr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2TGJKoqjQUZC7UKr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2TGJKoqjQUZC7UKr .marker.cross{stroke:#333333;}#mermaid-svg-2TGJKoqjQUZC7UKr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2TGJKoqjQUZC7UKr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .cluster-label text{fill:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .cluster-label span{color:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .label text,#mermaid-svg-2TGJKoqjQUZC7UKr span{fill:#333;color:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .node rect,#mermaid-svg-2TGJKoqjQUZC7UKr .node circle,#mermaid-svg-2TGJKoqjQUZC7UKr .node ellipse,#mermaid-svg-2TGJKoqjQUZC7UKr .node polygon,#mermaid-svg-2TGJKoqjQUZC7UKr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2TGJKoqjQUZC7UKr .node .label{text-align:center;}#mermaid-svg-2TGJKoqjQUZC7UKr .node.clickable{cursor:pointer;}#mermaid-svg-2TGJKoqjQUZC7UKr .arrowheadPath{fill:#333333;}#mermaid-svg-2TGJKoqjQUZC7UKr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2TGJKoqjQUZC7UKr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2TGJKoqjQUZC7UKr .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-2TGJKoqjQUZC7UKr .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-2TGJKoqjQUZC7UKr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2TGJKoqjQUZC7UKr .cluster text{fill:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr .cluster span{color:#333;}#mermaid-svg-2TGJKoqjQUZC7UKr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2TGJKoqjQUZC7UKr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

将连接管理集成到 Zinx 框架
将 ConnManager 加入 Server 模块
给 server 添加一个 ConnMgr 属性
修改 NewServer 方法,加入 ConnMgr 初始化
判断当前连接数量是否超出最大值 MaxConn
当 server 停止的时候,清除所有连接
Stop() 方法中加入 ConnMgr.ClearConn()
每次与客户端建立连接后,添加连接到 ConnManager 中
在 NewConnection 的时候将新的 conn 加入到 ConnMgr 中
需要给 Connection 加入隶属的 Server 属性
给 Server 提供一个 GetConnMgr 方法
每次与客户端连接断开后,将连接从 ConnManager 删除
在 Conn.Stop() 方法中,将当前的连接从 ConnMgr 删除即可
当 Server 停止的时候应该清除所有的连接
Stop() 方法中加入 ConnMgr.ClearConn()

9.4 注册链接启动/停止自定义 Hook 方法功能

给 ZInx 框架提供:创造连接之后 / 销毁连接之前 所要处理的一些业务,提供给用户能够注册的 Hook 函数

#mermaid-svg-vXBMLZqNRlk0lypI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .error-icon{fill:#552222;}#mermaid-svg-vXBMLZqNRlk0lypI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vXBMLZqNRlk0lypI .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-vXBMLZqNRlk0lypI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vXBMLZqNRlk0lypI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vXBMLZqNRlk0lypI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vXBMLZqNRlk0lypI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vXBMLZqNRlk0lypI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vXBMLZqNRlk0lypI .marker.cross{stroke:#333333;}#mermaid-svg-vXBMLZqNRlk0lypI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vXBMLZqNRlk0lypI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .cluster-label text{fill:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .cluster-label span{color:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .label text,#mermaid-svg-vXBMLZqNRlk0lypI span{fill:#333;color:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .node rect,#mermaid-svg-vXBMLZqNRlk0lypI .node circle,#mermaid-svg-vXBMLZqNRlk0lypI .node ellipse,#mermaid-svg-vXBMLZqNRlk0lypI .node polygon,#mermaid-svg-vXBMLZqNRlk0lypI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vXBMLZqNRlk0lypI .node .label{text-align:center;}#mermaid-svg-vXBMLZqNRlk0lypI .node.clickable{cursor:pointer;}#mermaid-svg-vXBMLZqNRlk0lypI .arrowheadPath{fill:#333333;}#mermaid-svg-vXBMLZqNRlk0lypI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vXBMLZqNRlk0lypI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vXBMLZqNRlk0lypI .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-vXBMLZqNRlk0lypI .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-vXBMLZqNRlk0lypI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vXBMLZqNRlk0lypI .cluster text{fill:#333;}#mermaid-svg-vXBMLZqNRlk0lypI .cluster span{color:#333;}#mermaid-svg-vXBMLZqNRlk0lypI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vXBMLZqNRlk0lypI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

提供 Hook 函数
添加的属性
该 Server 创建连接之后自动调用 Hook 函数
OnConnStart func(conn ziface.IConnection)
该 Server 销毁连接之前自动调用 Hook 函数
OnConnStop func(conn ziface.IConnection)
添加的方法
注册 OnConnStart 钩子函数的方法
SetOnConnStart(func(conn IConnection))
调用 OnConnStart 钩子函数的方法
CallOnConnStart(conn IConnection)
注册 OnConnStop 钩子函数的方法
SetOnConnStop(func(conn IConnection))
调用 OnConnStop 钩子函数的方法
CallOnConnStop(conn IConnection)
Conn 创建之后调用 OnConnStart
在 conn.Start() 中调用
Conn 销毁之前调用 OnConnStop
在 conn.Stop() 中调用

9.5 使用 Zinx-V0.9 完成应用程序

#mermaid-svg-tOED3aabNUnp9MXx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-tOED3aabNUnp9MXx .error-icon{fill:#552222;}#mermaid-svg-tOED3aabNUnp9MXx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tOED3aabNUnp9MXx .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-tOED3aabNUnp9MXx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tOED3aabNUnp9MXx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tOED3aabNUnp9MXx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tOED3aabNUnp9MXx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tOED3aabNUnp9MXx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tOED3aabNUnp9MXx .marker.cross{stroke:#333333;}#mermaid-svg-tOED3aabNUnp9MXx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tOED3aabNUnp9MXx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tOED3aabNUnp9MXx .cluster-label text{fill:#333;}#mermaid-svg-tOED3aabNUnp9MXx .cluster-label span{color:#333;}#mermaid-svg-tOED3aabNUnp9MXx .label text,#mermaid-svg-tOED3aabNUnp9MXx span{fill:#333;color:#333;}#mermaid-svg-tOED3aabNUnp9MXx .node rect,#mermaid-svg-tOED3aabNUnp9MXx .node circle,#mermaid-svg-tOED3aabNUnp9MXx .node ellipse,#mermaid-svg-tOED3aabNUnp9MXx .node polygon,#mermaid-svg-tOED3aabNUnp9MXx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tOED3aabNUnp9MXx .node .label{text-align:center;}#mermaid-svg-tOED3aabNUnp9MXx .node.clickable{cursor:pointer;}#mermaid-svg-tOED3aabNUnp9MXx .arrowheadPath{fill:#333333;}#mermaid-svg-tOED3aabNUnp9MXx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tOED3aabNUnp9MXx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tOED3aabNUnp9MXx .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-tOED3aabNUnp9MXx .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-tOED3aabNUnp9MXx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tOED3aabNUnp9MXx .cluster text{fill:#333;}#mermaid-svg-tOED3aabNUnp9MXx .cluster span{color:#333;}#mermaid-svg-tOED3aabNUnp9MXx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tOED3aabNUnp9MXx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

添加
使用 Zinx V0.9 进行开发
注册钩子函数的步骤

V0.9 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V0.9/(选择 V0.9 分支)

Zinx - V1.0 连接属性配置

十、Zinx 的连接属性设置

10.1 给连接添加连接配置接口

10.2 连接属性方法实现

#mermaid-svg-kMf459baf3j3Y9lG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-kMf459baf3j3Y9lG .error-icon{fill:#552222;}#mermaid-svg-kMf459baf3j3Y9lG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kMf459baf3j3Y9lG .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-kMf459baf3j3Y9lG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kMf459baf3j3Y9lG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kMf459baf3j3Y9lG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kMf459baf3j3Y9lG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kMf459baf3j3Y9lG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kMf459baf3j3Y9lG .marker.cross{stroke:#333333;}#mermaid-svg-kMf459baf3j3Y9lG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kMf459baf3j3Y9lG .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kMf459baf3j3Y9lG .cluster-label text{fill:#333;}#mermaid-svg-kMf459baf3j3Y9lG .cluster-label span{color:#333;}#mermaid-svg-kMf459baf3j3Y9lG .label text,#mermaid-svg-kMf459baf3j3Y9lG span{fill:#333;color:#333;}#mermaid-svg-kMf459baf3j3Y9lG .node rect,#mermaid-svg-kMf459baf3j3Y9lG .node circle,#mermaid-svg-kMf459baf3j3Y9lG .node ellipse,#mermaid-svg-kMf459baf3j3Y9lG .node polygon,#mermaid-svg-kMf459baf3j3Y9lG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kMf459baf3j3Y9lG .node .label{text-align:center;}#mermaid-svg-kMf459baf3j3Y9lG .node.clickable{cursor:pointer;}#mermaid-svg-kMf459baf3j3Y9lG .arrowheadPath{fill:#333333;}#mermaid-svg-kMf459baf3j3Y9lG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kMf459baf3j3Y9lG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kMf459baf3j3Y9lG .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-kMf459baf3j3Y9lG .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-kMf459baf3j3Y9lG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kMf459baf3j3Y9lG .cluster text{fill:#333;}#mermaid-svg-kMf459baf3j3Y9lG .cluster span{color:#333;}#mermaid-svg-kMf459baf3j3Y9lG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kMf459baf3j3Y9lG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

新增
新增
给 Connection 模块添加可以配置属性的功能
属性
连接属性集合 - property map[string]interface{}
保护连接属性的锁 - propertyLock sync.RWMutex
方法
设置连接属性 - SetProperty(key string, value interface{})
获取连接属性 - GetProperty(key string) (interface{}, error)
修改连接属性 - RemoveProperty(key string)

10.3 连接属性 Zinx-V0.10 单元测试

V1.0 版本的代码:https://gitee.com/szluyu99/my-zinx/tree/V1.0/(选择 V1.0 分支)

【Go 框架开发】Zinx 框架开发笔记相关推荐

  1. [iOS开发]——系统框架(effectiveOC2.0阅读笔记)

    系统框架 第47条:熟悉系统框架 要点 第48条:多用块枚举,少用for循环 for循环 使用 Objective-C 1.0的 NSEnumerator 来遍历 快速遍历 基于块的遍历方式 要点 第 ...

  2. 框架详解_Qt开发技术:QtCharts(一)QtCharts基本介绍以及图表框架详解

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  3. Python Web开发——Django框架学习

    文章目录 Web开发简介 Web应用技术 Web前端开发 Web后端开发 使用 Django 开发后端服务 项目目标 管理员操作 登录界面 客户管理界面 添加客户界面 药品管理界面 添加药品界面 订单 ...

  4. 【安卓开发系列 -- APP 开源框架】IO 框架 OKIO

    [安卓开发系列 -- APP 开源框架]IO 框架 OKIO [1]OKIO的整体框架 [1.1]OKIO的整体框架图示 [1.2]OKIO的优势 CPU和内存消耗低,OKIO采用了segment机制 ...

  5. 从零开始搭建一个GIS开发小框架(一)——基本框架

    目录 1.概述 1.1 项目背景 1.2 传送门 2.技术选型:GMap.NET 3.底图功能实现 2.1 方式一:在线地图(以高德为例) 2.2 greatmaps生成底图(瓦片地图) 3.搭建主程 ...

  6. 移动端app开发,框架的选择。

    从事java开发快三年了,最近公司因项目要求需要做一款app,个人对这方面兴趣比较大,于是网上收集资料,框架的选择,技术的论证,到今天项目需求的各个功能都做出了相应的demo同时也打好了框架,接下来就 ...

  7. 基于Stripes框架进行Java Web开发

    Mark Eagle是美国乔治亚州亚特兰大市MATRIX Resources有限公司的一位资深软件工程师,拥有Sun公司的SCP和SCWCD认证.Mark本人非常喜欢使用开源软件进行软件开发,并且多次 ...

  8. 微软一站式开发技术框架解决方案 年内展望

    微软一站式开发技术框架解决方案 (CodeFx) 自成立至今已有半年.在这半年里,我们完成了130个代码示例,主要覆盖了COM.数据访问.库加载.进程间通信.Office开发.WinForms等技术. ...

  9. Java可视化开发开源框架

    SpringBoot经典之作 进入Spring Boot世界 准备开发环境搭建开发工具 基础 Spring Boot基础 分层开发Web应用程序 响应式编程 进阶 Spring Boot进阶 用ORM ...

最新文章

  1. thinkpad触控笔怎么用_电容笔怎么用,如何选择一支电容笔来提升生产力呢?
  2. vue init webpack缺少标识符_vue 如何从单页应用改造成多页应用_vue.js
  3. Http Message Converters with the Spring Framework--转载
  4. java时间比较_广州java培训大概多久时间可以毕业
  5. 关于bufferKnife8.8.1点击事件无效的原因
  6. 设计模式:面向对象的设计原则下(ISP、DIP、KISS、YAGNI、DRY、LOD)
  7. php 建立自己的框架,利用 Composer 一步一步构建自己的 PHP 框架(一)——基础准备...
  8. 前端js获取图片大小 扩展名_前端 JS 获取 Image 图像 宽高 尺寸
  9. OJ1017: 表面积和体积
  10. Golang结构体与面向对象
  11. 确认!字节跳动 AI Lab 负责人马维英离职,将赴清华加入张亚勤团队
  12. 从 Ops 到 NoOps,阿里文娱智能运维的关键:自动化应用容量管理
  13. 拯救天使 (BFS)
  14. DataGrid实现单选功能,将DataGrid绑定的单选钮放在一个组里
  15. 国企,私企与外企利弊通观--关键时刻给应届毕业生及时点拨(二)
  16. sharelist+RaiDriver将阿里云盘映射到本地磁盘
  17. python基础以及面向对象
  18. 数据结构物理存储方式
  19. 计算机二级大题知识点汇总,计算机二级Excel考点与做题技巧汇总。
  20. MT29F8G08ABACA nandflash 参数记录

热门文章

  1. 大到创业,小到做一份副业
  2. solidity数据位置
  3. P1 Human Pose Estimation人体姿态综述估计调研
  4. 在Power BI Desktop中实施星型架构
  5. HDU 1281 棋盘游戏 【二分图最大匹配】
  6. find命令用法集锦
  7. 删除一个用户下的所有表脚本
  8. std::list 源代码解析
  9. .NET中获取字符串的MD5码
  10. MSSQL自增字段默认值