laravel-swoole和websocket入门(二)
2020-06-16 本文已影响0人
小牛_6666
在laravel-swoole和websocket入门(一)中,我们已经就 扩展的安装和启动作了介绍, laravel-swoole除了能大幅度的提升系统性能之后,还有一个很大的功能是 websocket长链接,这篇将详细介绍长链接部分。
1,启动长链接
- 首先我们要开放端口,比如我们要启动1215端口为长链接端口,那么服务器要先放行1215端口,具体放行的方法各种服务器不一样,就不细说了。
- 修改 config/swoole_http.php 部分配置
'server' => [
//服务地址 用0.0.0.0代替127.0.0.1 具体原因不知,反正127.0.0.1连不上
'host' => env('SWOOLE_HTTP_HOST', '0.0.0.0'),
'port' => env('SWOOLE_HTTP_PORT', '1215'),
//是否后台运行,测试阶段可以不用后台运行,方便查看运行状态 生产的时候后台运行
'daemonize' => env('SWOOLE_HTTP_DAEMONIZE', false),
]
'websocket' => [
//这里是 websocket的总开关, true和falsefalse,看着办
'enabled' => env('SWOOLE_HTTP_WEBSOCKET', true),
],
- 在路由文件里输出下测试 route/websocket.php
Websocket::on('connect', function ($websocket, Request $request) {
echo "connect";
// called while socket on connect
});
Websocket::on('disconnect', function ($websocket) {
// called while socket on disconnect
echo "disconnect";
});
现在我们启动服务,链接测试一下
php artisan swoole:http restart
客户端可以使用这个网站来测试
在控制台我们可以看到连接成功的提示
微信截图_20200616154928.png
查看代码
2,如何接收客户端发送的信息,并在系统中进行业务处理
建立一个长链接并不难,网上也有很多其他的方法,一个单文件脚本就可以建起长链接,但是我们很难在一个单文件里进行复杂的业务处理。使用 swoole-websocket,我们可以很方便的把长链接发送的数据经过路由转到 Controller,就像处理正常的 http请求一样,处理websocket, laravel里面的大部分功能都可以正常使用,如 Model,Cache等。可以和我们的业务逻辑高度契合。
- 首先我们约定所有的数据传输都是 json格式,必须包含两个字段event,data。event就类似于请求的 route路由, data是请求的数据
{
"event": "login",
"data": {
"uid": 1
}
}
返回的数据也是类似
{
"event": "return",
"data": "我收到了你的消息{"uid":1}"
}
以下是大概思路,具体还请查看代码
- 1,创建一个WebsocketHandler类,放在哪都行,我是放在了 app\Swoole
这个类主要是对 websocket的一个操作类,有三个事件onOpen
,onMessage
,onClose
,我这里只用了 onOpen事件,就是长链接建立链接事件,这里我要返回 fd(客户端的一个编号,后面所有向客户端发信息都需要这个 fd),当然也可以做其他的处理
public function onOpen($fd, Request $request)
{
/**
* 客户端建立起长链接后,返回客户端fd
*/
$this->server->push($fd, json_encode(['event' => 'open', 'data' => ['fd' => $fd]]));
return true;
}
链接建立后客户端会收到信息
{
"event": "open",
"data": {
"fd": 2
}
}
- 2,创建一个Parser类,仍然放在app\Swoole
这个类主要是对长链接传送的数据进行 encode和 decode,如果不想用 json或者有其他的数据转换可以在这里面
public function encode(string $event, $data)
{
$string = ['event' => $event, 'data' => $data];
return json_encode($string);
}
public function decode($frame)
{
//这里是解析客户端发来的数据,我们约定所有的传输都是json
$json = $frame->data;
$data = json_decode($json, true);
if (!$data || !isset($data['event'])) {
return ['event' => 'error', 'data' => $frame->data];
}
return ['event' => $data['event'], 'data' => $data['data'] ?? ''];
}
- 3,创建一条路由,route/websocket.php
/**
* 定义一个login路由,指向控制器方法,和http类似
*/
Websocket::on('login','App\Http\Controllers\Index\LoginController@index');
- 4,修改 config/swoole_websocket.php config/swoole_websocket.php,设置我们刚才自已添加的两个类
'handler' => \App\Swoole\WebsocketHandler::class,
'parser' => \App\Swoole\Parser::class,
- 5, 创建控制器方法App\Http\Controllers\Index\LoginController
public function index(Websocket $websocket, $data)
{
/**
* 这里就可以做业务处理,比如绑定用户和fd等
*/
$websocket->emit('return', "我收到了你的消息" . json_encode($data));
}
这里面注入两个变量,一个是 websocket,用来操作 websocket的,比如回复信息,data就是客户端发送的数据
到此就可以测试了
微信截图_20200616172054.png
查看代码
有问题请留言
未完待续