IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 【dubbo-getty】入门篇—架构剖析 -> 正文阅读

[网络协议]【dubbo-getty】入门篇—架构剖析

简介

dubbo-getty 是一个用 go 编写的异步网络 I/O 库,提供了三种通信模式,tcp、udp 以及 websocket,并为其设计了相对统一的流程和 API,目前 dubbogo 等知名项目都使用 getty 作为底层的网络通信库,其特点是封装性好,使用简单。下图是 getty 核心结构的类图,基本囊括了整个 getty 框架的设计。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4De7fC3w-1629357191447)(/img/bVcUcGO)]

灰色部分为 go 内置库

下面以 TCP 为例介绍下 getty 如何使用以及该类图里各个接口或对象的作用。

TCP Server 端

server

其中 server/client 是提供给用户使用的封装好的结构,client 的逻辑与 server 很多程度上一致,因此这里只讲 server。

在 getty 中,server 服务的启动流程只需要两行代码

server := getty.NewTCPServer(options...)
server.RunEventLoop(NewHelloServerSession)

第一行非常明显是一个创建 server 的过程,options 是一个个 func(*ServerOptions) 函数,用于给 server 添加一些额外功能设置,如启用 ssl,使用任务队列提交任务的形式执行任务等。

第二行的 server.RunEventLoop(NewHelloServerSession) 则是启动 server,同时也是整个 server 服务的入口,它的作用是监听某个端口(具体监听哪个端口可以通过 options 指定),并处理 client 发来的数据。RunEventLoop 方法需要提供一个参数 NewSessionCallback,该参数的类型定义如下:

type NewSessionCallback func(Session) error

这是一个回调函数,将在成功建立和 client 的连接后被调用,一般提供给用户用于设置网络参数,如设置连接的 keepAlive 参数、缓冲区大小、最大消息长度、read/write 超时时间等,但最重要的是,用户需要通过该函数,为 session 设置好要用的 Reader、Writer 以及 EventListener。

Session

Session 可以说是 getty 中最核心的接口了,每个 Session 代表着一次会话连接,向下,Session 对 go 内置的网络库做了完善的封装,包括对 net.Conn 的数据流读写、超时机制等,向上,Session 提供了业务可切入的接口,用户只需实现 EventListener 就可以将 getty 接入到自己的业务逻辑中。目前 Session 接口的实现只有 session 结构体,Session 作为接口仅仅是提供了对外可见性以及遵循面向编程接口的机制,之后我们谈到 Session,其实都是在讲 session 结构体。

Connection

Connection 则是刚提到的,Session 向下对于 go 内置网络库的抽象封装,根据不同的通信模式,Connection 分别有三种实现:

  • gettyTCPConn:底层是 *net.TCPConn
  • gettyUDPConn:底层是 *net.UDPConn
  • gettyWSConn:底层使用第三方库实现

EventListener

EventListener 则对应 Session 向上开放给用户的接口,用户需要在该接口的实现中封装好业务逻辑,由 session 在运行的过程中调用。EventListener 接口的定义如下

// EventListener is used to process pkg that received from remote session
typeEventListenerinterface{
    // invoked when session opened
    // If the return error is not nil, @Session will be closed.
    OnOpen(Session) error
		
    // invoked when session closed.
    OnClose(Session)
		
    // invoked when got error.
    OnError(Session, error)
		
    // invoked periodically, its period can be set by (Session)SetCronPeriod
    OnCron(Session)
		
    // invoked when getty received a package. Pls attention that do not handle long time
    // logic processing in this func. You'd better set the package's maximum length.
    // If the message's length is greater than it, u should should return err in
    // Reader{Read} and getty will close this connection soon.
    //
    // If ur logic processing in this func will take a long time, u should start a goroutine
    // pool(like working thread pool in cpp) to handle the processing asynchronously. Or u
    // can do the logic processing in other asynchronous way.
    // !!!In short, urOnMessage callback func should return asap.
    //
    // If this is a udp event listener, the second parameter type isUDPContext.
    OnMessage(Session, interface{})
}

这五个接口中最核心的是 OnMessage 方法,该方法有一个 interface{} 类型的参数,用于接收 client 端发来的数据。可能大家有个疑惑,网络连接最底层传输的是二进制,到我们使用的协议层一般以字节流的方式对连接进行读写,那这里为什么要使用 interface{} 呢?这是 getty 为了让我们能够专注编写业务逻辑,将序列化和反序列化的逻辑抽取到了 EventListener 外面,也就是前面提到的 Reader/Writer 接口,session 在运行过程中,会先从 net.Conn 中读取字节流,并通过 Reader 接口进行反序列化,再将反序列化的结果传递给 OnMessage 方法。

Writer/Reader

Writer 和 Reader 分别是序列化/反序列化接口,两者的定义非常简单,都只有一个方法。

type Reader interface{
	Read(Session, []byte) (interface{}, int, error)
}

type Writer interface{
	Write(Session,interface{}) ([]byte, error)
}

具体的序列化/反序列化逻辑则交给了用户手动实现,其中 Reader 接口之前提过,当 server 端读取了 client 发送的字节流后,会调用它的 Read 方法进行反序列化。而 Writer 接口则是在 client 端被使用,当 client 发送数据时,需要调用 Write 方法将发送的数据序列化为字节流,再写入到 net.Conn 中。

至此,getty 中 server 的处理流程大体如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dG2de0aG-1629357191449)(/img/bVcUcGH)]

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-20 15:27:26  更:2021-08-20 15:28:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:17:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码