Laravel + Swoole 实现更快的请求处理速度、更高并发有扩展包可供选择,那么如何在 Laravel 框架内优雅地嵌入 Swoole 实现 TCP/UDP Socket 服务端呢?
0x00 Why
先说说为什么要嵌入 Laravel 吧。
就一个原因:
Eloquent ORM
物联网场景下,Swoole 作为与硬件对接的后端服务,接收到硬件发来的数据包后,多数情况需要直接入库,所以有一个方便易用的 ORM 就显得尤为重要重要。
而目前公司的情况,我们与 Web 端对接的后端框架是 Laravel;若是能结合一下,又能利用现成的数据模型,不需要再重复定义,岂不是美滋滋~
0x01 How
首先创建项目:laravel new
根据 Server - Swoole 文档,「swoole_server 只能用于 php-cli 环境」,而 Laravel 提供的 Artisan 命令行 功能就是基于 PHP-CLI 的;
按照这个思路,我们可以创建一条名为swoole:start
的 Artisan Command,不需要破坏框架原有结构,部署时只需要执行此命令启动 Swoole 服务端监听硬件通信端口即可。
0x01 Just do it!
创建命令类
php artisan make:command Swoole
其中,Swoole 是类名。
修改必要参数
执行后会在app/Console/Commands/
文件夹内创建一个与类名相同的 php 文件,这就是你的命令类。
/**
* 执行此命令时所需的命令名。
*
* @var string
*/
protected $signature = 'swoole:start';
/**
* 此命令的描述。
*
* @var string
*/
protected $description = 'Command description';
如上,你可以修改成员变量定义命令的名称和描述。
引用数据库门面或模型
使用 Artisan 创建的命令类默认是不引用数据库门面的,所以我们需要在文件头部加入:
use Illuminate\Support\Facades\DB;
//或者你可以 use 所需的 Model:
use App\User;
处理此命令
修改handle
成员函数,此方法会在此命令被执行的时候调用,加入启动 Swoole 的代码即可。
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$server = new \swoole_server("127.0.0.1", 9503);
// 收到连接请求
$server->on('connect', function ($server, $fd) {
echo "connection open: {$fd}\n";
//数据入库
DB::table('users')->insert(
['username' => 'testu', 'password' => 'testp']
);
});
// 收到数据包
$server->on('receive', function ($server, $fd, $reactor_id, $data) {
$server->send($fd, "Swoole: {$data}");
$server->close($fd);
});
// 断开连接
$server->on('close', function ($server, $fd) {
echo "connection close: {$fd}\n";
});
// 启动服务
$server->start();
}
注意:new \swoole_server(...);
不要忘记反斜线(\),这是表示在全局命名空间下的类,具体可查看 PHP 文档:全局空间。
以上代码即可实现,客户端连接时立即向数据库加入一条记录。
启动
现在,命令行执行php artisan swoole:start
,不会有任何输出,别担心,这是正常的,Swoole 已经启动了。
接着新打开一个命令行窗口,执行telnet 127.0.0.1 9503
。
Telnet 是一个类似 SSH 的东西,现在基本已经被淘汰,但 Telnet 客户端仍常用来测试 TCP 连接。更多关于 Telnet 的知识,可参考:telnet 命令
这时,可以看到执行 Artisan 命令的窗口会输出:
connection open: 1
检查数据库,数据成功插入。
完成!
0x02 More
MacOS 安装 Telnet
brew install telnet
MacOS 安装 Swoole
首先使用 brew list | grep php
查看你电脑上的 PHP 版本。
检索所有的 Swoole:
brew search swoole
根据不同 PHP 版本安装对应 Swoole 即可,我的电脑是php71
,所以执行:
brew install php71-swoole
0x03 The End
有空会考虑封装个扩展包。
另外,贴几个开头提到的「利用 Swoole 处理 PHP 请求提升 Laravel 速度」的现成扩展包: