二、Swoole 基础学习笔记 - 先把 Swoole 跑起来
hi,我是温新,一名PHPer
文章基于 Swoole 5.0 版本编写。
学习目标:运行 Swoole 服务
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
学习 Swoole,把它下载下来,然后跑起来,再追究其根本。如下,一起来运行 Swoole 服务吧!
Swoole 跑起来
1)编写代码
<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(209, 154, 102) !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">// 1-swoole-run.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(224, 108, 117) !important">$server</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(209, 154, 102) !important">Swoole\Server</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'0.0.0.0'</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">SWOOLE_PROCESS</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(224, 108, 117) !important">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Connect'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</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">$fd</span> . <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">' 客户端连接'</span> . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</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"></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">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Receive'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$reactorId</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</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">$server</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">send</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</span>, <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'服务器返回:'</span> . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</span>) . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</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"></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">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Close'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</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">'客户端断开连接'</span> . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</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"></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">$server</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">start</span>();</span>
2)命令行运行文件
<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">// 启动 swoole 服务</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(209, 154, 102) !important">php</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">server</span>.<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">php</span></span>
3)客户端连接服务端
<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">// 重新开一个端口,使用 telnet 进行连接</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(209, 154, 102) !important">telnet</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">192.168</span>.<span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">10.121</span> <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">9501</span></span>
这样,swoole 服务已经跑起来,并且通过 telnet 进行连接,连接后在服务端可以到 1 客户端连接
的输出。如此,一个 swoole 服务成功的跑起来了。服务跑起来了,再来看看这些代码的含义。
了解 Swoole 代码含义
1)实例化一个 server 对象
<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">// 实例 Server 对象,监听 0.0.0.0:9501 端口</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">$server</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(209, 154, 102) !important">Swoole\Server</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'0.0.0.0'</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">SWOOLE_PROCESS</span>);</span>
实例 Server 对象,需要绑定监听的 IP 和端口。若 IP 地址指定为 127.0.0.1
,则表示只有李本机客户端才能连接服务端,0.0.0.0
则表示任何客户端都可以连接服务端。
2)监听客户端连接
<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(224, 108, 117) !important">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Connect'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</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">// 输出有客户端连接信息</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">$fd</span> . <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">' 客户端连接'</span> . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span>
监听客户端连接,当有客户端连接时,触发回调函数执行。毁掉函数中有两个参数,$server
和 $fd
,其含义分别为:实例化 Server 对象;客户端连接标识。
3)接收客户端发送的数据
<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(224, 108, 117) !important">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Receive'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$reactorId</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</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">// 服务端收到客户端数据后,再将数据发送给客户端</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">$server</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">send</span>(<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</span>, <span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'服务器返回:'</span> . <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$data</span>) . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span>
Recevie
回调中有 4 个参数,$server 和 $fd 与 2)是一样的,现在来说说后面两个参数的含义。
参数 $reactorId
指的是哪一个 reactor 线程;
参数 $data
客户端发送的数据(服务端接收到的数据是字符串或二进制内容)。
4)监听客户端断开连接或服务器端主动关闭连接事件
<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(224, 108, 117) !important">$server</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">on</span>(<span style="box-sizing: border-box;color: rgb(152, 195, 121) !important">'Close'</span>, <span style="box-sizing: border-box;color: rgb(198, 120, 221) !important">function</span> (<span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$server</span>, <span style="box-sizing: border-box;color: rgb(224, 108, 117) !important">$fd</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">'客户端断开连接'</span> . <span style="box-sizing: border-box;color: rgb(209, 154, 102) !important">PHP_EOL</span>;</span><br></br><span style="box-sizing: border-box;color: rgb(171, 178, 191);padding-right: 0.1px">});</span>
5)启动服务
<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">// 启动 server 服务</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">$server</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">start</span>();</span>
Swoole Server 服务的代码含义就了解到这里了,下面再看看其他的,当前使用 php server.php
启动服务后发生了什么?
服务启动后发生了什么
与传统的 Web 服务不一样,最直观的感觉就是:传统 Web 通过浏览器来访问,而 Swoole 服务需要在 Cli 模式中执行。当启动服务后,就会发现服务被阻塞了,只有光标在一闪一闪的,别着急,正因如此,Swoole 服务才启动了。下面就来看看,服务启动后发生了什么。
1)ps 查看进程
<span style="color: rgb(255, 192, 0);">$ps aux | grep 9501<br></br>codeing 22469 0.0 0.0 13864 892 pts/2 S+ 00:11 0:00 grep 9501</span><br></br>
仔细看看结果,9501 不正是我们所监听的端口吗,进程被挂起。
2)查看 server 服务
<span style="color: rgb(255, 192, 0);">$ps aux | grep php<br></br>codeing 19309 0.0 0.1 703684 27336 pts/1 Sl+ 11月24 0:00 php 1-swoole-run.php<br></br>codeing 19310 0.0 0.0 115844 8008 pts/1 S+ 11月24 0:00 php 1-swoole-run.php<br></br>codeing 19319 0.0 0.0 118044 10704 pts/1 S+ 11月24 0:00 php 1-swoole-run.php</span><br></br>
咦,有 1-swoole-run.php
,这正是我们的文件名,有 3 个之多(当然不是 3 个了,与电脑 CPU 核数有关,这里暂且不谈),这就是运行了 3 个进程。相关含义下一篇文章中进行学习。
到这里进行一个总结,启动 server 后,我们知道了,会有相关的进程被创建,而这些进程就是用来处理任务的。先对它进行一个眼熟,下面再来创建一个客户端,让这个客户端与服务器进行连接。
创建一个客户端与服务端连接
1)客户端代码
<span style="color: rgb(255, 192, 0);"><?php<br></br>// 1-swoole-client.php<br></br><br></br>// 实例一个 tcp 客户端<br></br>$client = new Swoole\Client(SWOOLE_SOCK_TCP);<br></br><br></br>// 连接服务端<br></br>if (! $client->connect('127.0.0.1', 9501)) {<br></br> exit('连接服务端失败 ' . $client->errCode . PHP_EOL);<br></br>}<br></br><br></br>// 向服务端发送消息<br></br>$client->send('Client: hello swoole' . PHP_EOL);<br></br><br></br>// 输出服务端返回的消息<br></br>echo $client->recv();<br></br><br></br>// 关闭连接<br></br>$client->close();</span><br></br>
2)运行客户端
<span style="color: rgb(255, 192, 0);">php 1-swoole-client.php<br></br> <br></br># 输出信息<br></br>$php 1-swoole-client.php <br></br>服务器返回:Client: hello swoole</span><br></br>
本篇文章到此结束,我是温新