五、Swoole 基础学习笔记 - 深入学习 Tcp Server
hi,我是温新,一名PHPer
文章基于 Swoole 5.0 版本编写。
**学习目标:学习 Swoole Tcp Server **
说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!
在 Swoole 基础学习笔记 - 先把 Swoole 跑起来 篇章中,使用 Tcp 案例进行了一个简单的演示,本篇文章将对 Swoole Tcp 进行一个基础的学习,了解更多 Tcp 相关属性、方法、事件。关于回调函数参数问题,本篇文章不进行过多说明,详情请参考官方文档。
学习 Swoole/Server
如何启动一个 Server 服务
Swoole 中,如何创建一个 Server 服务?如下几步走:
- 1、实例化 Server 对象;
- 2、设置运行时参数(可选);
- 3、注册回调事件('Connect、Receive、Close');
- 4、启动 Server 服务
现在,动手实现一个 Server,代码如 下:
<?php
// 3-swoole-tcp.php
// 实例 Server 对象,监听 0.0.0.0:9501
$server = new Swoole\Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
// 设置参数
$server->set([
// 设置 worker 进程数量
'worker_num' => 2,
// 设置 reactor 线程数量
'reactor_num' => 3,
]);
// 监听客户端连接事件。客户端连接进来时触发
$server->on('Connect', function ($server, $fd, $reactorId) {
echo '有人连接进来了,是一个编号为 ' . $reactorId . ' 守卫把一个身份证号为 ' . $fd . ' 的家伙放进来了' . PHP_EOL;
});
// 监听数据接收事件。服务端收到客户端数据后,在 worker 进程中出发该回调
$server->on('Receive', function ($server, $fd, $fromId, $data) {
// 服务端收到消息后,通过 send 方法给客户端发送消息
$server->send($fd, 'Server:' . $fd . ' ,一起去看海啊');
});
// 监听连接关闭事件。客户端关闭,或服务端主动关闭
$server->on('Close', function ($server, $fd) {
echo '上班了,好好干';
});
// 启动服务器
$server->start();
已经有了详细的案例,那么下一步该如何操作相信大家都已经明白了。运行-测试 跑起来,这就是自己的事了。
现在开始对 Server 进行逐一分析:
1、实例化 Server 对象
创建一个 Server,只需要将其对象进行实例化操作,并指定需要绑定的 IP 地址及需要监听的 Port。若 IP 为 127.0.0.1,表示客户端只能是 本机
连接,其他客户端无法连接;若 IP 为 0.0.0.0,表示所有的客户端都能连接。
// 实例 Server 对象,监听 0.0.0.0:9501
$server = new Swoole\Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
2、设置运行时参数
在 Server 启动之前,可以对 Server 进行一些参数配置,如设置进程数量、线程数量、设置 worker 进程最大任务数等配置。如使用 PHP Cli 模式启动 Server 服务后,我们会看到服务一直被挂起,好像被阻塞了一样,不能做其他操作,当设置 daemonize
进行后台运行。
$server->set([
// 设置 worker 进程数量
'worker_num' => 2,
// 设置 reactor 线程数量
'reactor_num' => 3,
// 后台守护进行运行
// 'daemonize' => true,
]);
如何设置 worker_num
数量?官方建议设置为 CPU 核数的 1~4 倍
。进程并不是开的越多越好,若设置不合理可能会适得其反。进程开的越多,占用的内存也就越多,而进程切换也就需要消耗更多的资源。worker_num
默认为 CPU 核数。
- 启动成功后会创建
worker_num+2
个进程。Master
进程 +Manager
进程 +serv->worker_num
个Worker
进程。
根据现在的设置,来算算开启了多少个进程。答案是 4 个进程,你算对了吗?
3、注册事件回调函数
Swoole/Server 是事件驱动,我们只管使用而不用去关心底层是怎么实现的,当相对应的事件触发后,我们要做的是在回调函数中进行业务逻辑处理即可。
举一个例子,刷脸进门。我们只需要将脸部送进摄像头识别区域内,等待摄像头识别人脸处理,识别成功,门就开了,我们也就可以进去了。在这个过程我们几乎什么也没有做,只是把脸准了摄像头,然后门就开了。
对于我们自己创建的 Server 服务,也是一样的道理。启动一个 Server,客户端连接后触发回调函数,这个过程中,服务端不需要知道它是怎么连接进来的,总之它来了,来了,我们就可以处理,而处理就是在回调中。
// 监听客户端连接事件。客户端连接进来时触发
$server->on('Connect', function ($server, $fd, $reactorId) {
echo '有人连接进来了,是一个编号为 ' . $reactorId . ' 守卫把一个身份证号为 ' . $fd . ' 的家伙放进来了' . PHP_EOL;
});
需要注意的是,参数 $fd
是客户端的唯一标识(当做是身份证号),用于区分不同的客户端。该标识范围在 11~1600W
且是可以复用的整数,如现在有 3 个人连接进来了,其身份证分别为 1、2、3,现在有第四个人需要连接进来,此时刚好 2 关闭了连接,第 4 个人连接进来,它的 身份证号就是 2 了。
receive
回调,需要注意的是,参数 $data
是服务端接收到的数据,这个数据是 字符串
或二进制
内容。
4、启动 Server
Swoole/Server 只能在 Cli 模式中运行,因此不要试图使用浏览器来访问它。
// 启动服务器
$server->start();
完成这 4 个步骤,一个高性能的 Server 已经运行起来了。
$ps aux | grep php
codeing 28880 0.1 0.1 261328 27672 pts/2 Sl+ 23:02 0:00 php 3-swoole-tcp.php
codeing 28881 0.0 0.0 115892 8428 pts/2 S+ 23:02 0:00 php 3-swoole-tcp.php
codeing 28884 0.0 0.0 118084 10928 pts/2 S+ 23:02 0:00 php 3-swoole-tcp.php
codeing 28885 0.0 0.0 118084 10928 pts/2 S+ 23:02 0:00 php 3-swoole-tcp.php
为了避免文章篇幅过长,本篇 TCP 文章到此结束,我是温新,我们下篇文章见。