三十七、Swoole 基础学习笔记 - Swoole 协程 TCP/UDP 客户端
hi,我是温新,一名PHPer
文章基于 Swoole 5.0.1 版本编写。
学习目标:学习协程 TCP/UDP 服务器
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
协程 TCP/UDP 客户端
Coroutine\Client 提供了 TCP、UDP、unixSocket 传输协议的 Sockt 客户端封装代码,使用时仅需 new Swoole\Coroutine\Client
即可。
实现原理
- 1、
Coroutine\Client
的所有涉及网络请求的方法,Swoole
都会进行协程调度,业务层无感知; - 2、使用方法同 Client 同步模式方法完全一致;
- 3、
connect
超时设置同时作用于Connect
、Recv
和Send
超时。
继承关系
- 1、Coroutine\Client 与 Client 不是继承关系,但
Client
提供的方法均可在Coroutine\Client
中使用。 - 2、在
Coroutine\Client
中可以使用set
方法设置配置选项,使用方法和与Client->set
完全一致。
协议处理
协程客户端也支持长度和 EOF
协议处理,设置方法与 Swoole\Client 完全一致。
<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">new</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Coroutine\Client</span>(<span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">SWOOLE_SOCK_TCP</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">set</span>(<span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">array</span>(</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'open_length_check'</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">true</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'package_length_type'</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'N'</span>,</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'package_length_offset'</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0</span>, <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">//第N个字节是包长度的值</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'package_body_offset'</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">4</span>, <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">//第几个字节开始计算长度</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'package_max_length'</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=></span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">2000000</span>, <span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">//协议最大长度</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">));</span>
客户端案例
<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important"><?</span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important">// 37-swoole-coroutine-client.php</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Coroutine\run</span>(<span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> () {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span> <span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">=</span> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">new</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Coroutine\Client</span>(<span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">SWOOLE_SOCK_TCP</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">if</span> (<span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">!</span><span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">connect</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'127.0.0.1'</span>, <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">9501</span>, <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">0.5</span>)) {</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">echo</span> <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">"connect failed. Error: </span>{<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">errCode</span>}<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">\n"</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">send</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">"我是协程客户端\n"</span>);</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">echo</span> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">recv</span>();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">close</span>();</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span>
客户端 API
connect
含义:连接到远程服务器。
语法:Swoole\Coroutine\Client->connect(string $host, int $port, float $timeout = 0.5): bool
isConnected
含义:返回 Client 的连接状态。
语法:
<span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">Swoole\Coroutine\Client</span><span style="box-sizing: border-box;color: rgb(86, 182, 194) !important">-></span><span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">isConnected</span>(): <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">bool</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> </span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(98, 151, 85) !important"># 返回值</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">返回</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">false,表示当前未连接到服务器</span></span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">返回</span> <span style="box-sizing: border-box;color: rgb(18, 170, 228) !important">true,表示当前已连接到服务器</span></span>
send
含义:发送数据。
语法:Swoole\Coroutine\Client->send(string $data): int|bool
参数:$data
:为发送的数据,必须为字符串类型,支持二进制数据。
recv
含义:recv 方法用于从服务器端接收数据。
语法:Swoole\Coroutine\Client->recv(float $timeout = 0): string|bool
close
含义:关闭连接。
语法:Swoole\Coroutine\Client->close(): bool
peek
含义:窥视数据。
语法:Swoole\Coroutine\Client->peek(int $length = 65535): string
set
含义:设置客户端参数
语法:Swoole\Coroutine\Client->set(array $settings): bool
与 Swoole\Client
的差异:
协程客户端提供了更细粒度的超时控制。可以设置:
-
timeout
:总超时,包括连接、发送、接收所有超时 -
connect_timeout
:连接超时 -
read_timeout
:接收超时 -
write_timeout
:发送超时
我是温新,本篇文章结束。