Yar 源码阅读笔记:数据传输模块
文章目录
前言
在前面几篇文章中,更多的是在研究 Yar 传输的内容,比如协议的格式是什么样的、如何对数据进行编码等等。
今天这篇文章,主要介绍 Yar 编码模块的结构体定义,以及 HTTP 传输方式的实现,更深入的了解 Yar 的协议数据是如何被发送出去的。
传输模块结构体
在 RPC 通信协议 中有提到过,Yar 支持 HTTP 和 TCP 两种数据传输方式,前者使用 curl,后者使用 socket。
yar_transport_t
我们可以将 yar_transport_t 结构体看作是同步传输器的工厂,用于创建和释放同步传输器的实例。
1 | // source:yar_transport.h |
结构体字段说明:
- name:传输方式的名称,比如 “curl”。
- init:函数指针,创建同步传输器实例并初始化相关配置,函数的返回值是结构体 _yar_transport_interface 的指针。
- destroy:函数指针,释放某个同步传输器的资源,函数的参数是结构体 _yar_transport_interface 的指针。
- multi:用于实现并行调用的结构体指针,这部分会在并行调用进行详解。
yar_transport_interface_t
在 yar_transport_t 结构体中,只定义了 init 和 destroy 这两个函数指针,用于对同步传输器的创建和释放。而真正用于传输时使用的相关函数,则放在了 yar_transport_interface_t 结构体中。
1 | // source:yar_transport.h |
结构体说明:
- data:存储传输相关的数据指针,比如 curl 是 yar_curl_data_t 结构体,socket 是 yar_socket_data_t 结构体。
- open:函数指针,打开/创建一个连接,并初始化相关默认值。
- send:函数指针,对请求数据进行编码、组装等操作,并将处理后的数据保存到连接中。
- exec:函数指针,执行请求,将连接中的数据发送出去。
- setopt:函数指针,设置连接相关的选项,比如编码方式、超时时间。
- calldata:函数指针,设置回调时的数据,在并行调用时才会用到。
- close:函数指针:关闭连接并释放相关的资源。
HTTP 传输方式
Yar 支持的传输方式都放在了 transports 目录下,因为 HTTP 是 Yar 默认的数据传输方式,并且服务端也只实现了 HTTP 这种方式,所以我们这里用 HTTP 进行举例。
用 c 语言实现 HTTP 请求的类库有很多,Yar 使用的是 curl,所以在 transports 目录下的文件命名是 curl.c。
yar_transport_t
根据前面传输模块的介绍,首先需要实现 yar_transport_t 结构体。
1 | // source:transports/curl.c |
curl 是传输方式的名称,php_yar_curl_init 和 php_yar_curl_destroy 是 init 和 destroy 这两个函数指针的实现,yar_transport_curl_multi 用来实现并行调用。
先来看看 php_yar_curl_init 函数。
1 | // source:transports/curl.c |
由于没有资源需要在 destroy 的时候进行释放,所以 php_yar_curl_destroy 是一个空函数。
1 | // source:transports/curl.c |
yar_transport_interface_t
接下来看看 curl 中 yar_transport_interface_t 相关的实现。
首先是 php_yar_curl_open 函数,以下是该函数的主要逻辑:
- 如果开启了连接持久化,则尝试从持久化的连接池中找到未使用的连接。
- 没有找到符合条件的连接或者未开启连接持久化,则直接创建一个新的 curl 实例。
- 解析请求地址,并将请求信息及 curl 实例保存到 data 中,方便后续在其它函数中使用。
- 如果开启了连接持久化,则设置 keep-alive 及 keep-alive 有效时间的头部信息。
- 设置自定义的头部信息及域名。
- 设置 curl 收到响应时的回调函数及其它 curl 选项。
- 设置 curl 请求地址。
打开连接之后,调用 php_yar_curl_send 函数对请求数据进行编码、组装等操作。
1 | // source:transports/curl.c |
数据准备就绪后,就可以调用 php_yar_curl_exec 函数执行请求,将数据发送出去并解析响应结果。
1 | // source:transports/curl.c |
得到响应结果后,调用 php_yar_curl_close 关闭连接。
1 | // source:transports/curl.c |
总结
这次没有像上一篇文章那样,将传输模块的生命周期各个阶段都写出来,这是因为传输模块在 PHP 生命周期中的几个阶段做的事情跟编码模块差不多,所以就省略掉了。
通过本文可以看出来,Yar 中的 HTTP 传输方式,实际上是对 curl 的一层封装,我写了一个 curl 的小示例,供大家参考。
1 |
|
原文作者: her-cat
原文链接: https://her-cat.com/2022/01/06/yar-internals-transport.html
许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议