多端口混合协议
更多的信息,请参考Swoole增加监听的端口与多端口混合协议
为了使我们的主服务器能支持除HTTP
和WebSocket
外的更多协议,我们引入了Swoole
的多端口混合协议
特性,在LaravelS中称为Socket
。现在,可以很方便地在Laravel
上被构建TCP/UDP
应用。
- 创建Socket处理类,继承
Hhxsv5\LaravelS\Swoole\Socket{TcpSocket|UdpSocket|Http|WebSocket}
- namespace App\Sockets;
- use Hhxsv5\LaravelS\Swoole\Socket\TcpSocket;
- use Swoole\Server;
- class TestTcpSocket extends TcpSocket
- {
- public function onConnect(Server $server, $fd, $reactorId)
- {
- \Log::info('New TCP connection', [$fd]);
- $server->send($fd, 'Welcome to LaravelS.');
- }
- public function onReceive(Server $server, $fd, $reactorId, $data)
- {
- \Log::info('Received data', [$fd, $data]);
- $server->send($fd, 'LaravelS: ' . $data);
- if ($data === "quit\r\n") {
- $server->send($fd, 'LaravelS: bye' . PHP_EOL);
- $server->close($fd);
- }
- }
- public function onClose(Server $server, $fd, $reactorId)
- {
- \Log::info('Close TCP connection', [$fd]);
- $server->send($fd, 'Goodbye');
- }
- }
这些连接和主服务器上的HTTP/WebSocket连接共享Worker进程,因此可以在这些事件操作中使用LaravelS提供的异步任务投递
、SwooleTable
、Laravel提供的组件如DB
、Eloquent
等。同时,如果需要使用该协议端口的Swoole\Server\Port
对象,只需要像如下代码一样访问Socket
类的成员swoolePort
即可。
- public function onReceive(Server $server, $fd, $reactorId, $data)
- {
- $port = $this->swoolePort; //获得`Swoole\Server\Port`对象
- }
- 注册套接字。
- // 修改文件 config/laravels.php
- // ...
- 'sockets' => [
- [
- 'host' => '127.0.0.1',
- 'port' => 5291,
- 'type' => SWOOLE_SOCK_TCP,// 支持的嵌套字类型:https://wiki.swoole.com/wiki/page/16.html#entry_h2_0
- 'settings' => [// Swoole可用的配置项:https://wiki.swoole.com/wiki/page/526.html
- 'open_eof_check' => true,
- 'package_eof' => "\r\n",
- ],
- 'handler' => \App\Sockets\TestTcpSocket::class,
- ],
- ],
关于心跳配置,只能设置在主服务器
上,不能配置在套接字
上,但套接字
会继承主服务器
的心跳配置。
对于TCP协议,dispatch_mode
选项设为1/3
时,底层会屏蔽onConnect
/onClose
事件,原因是这两种模式下无法保证onConnect
/onClose
/onReceive
的顺序。如果需要用到这两个事件,请将dispatch_mode
改为2/4/5
,参考。
- 'swoole' => [
- //...
- 'dispatch_mode' => 2,
- //...
- ];
测试。
TCP:
telnet 127.0.0.1 5291
UDP:Linux下
echo "Hello LaravelS" > /dev/udp/127.0.0.1/5292
其他协议的注册示例。
- UDP
- 'sockets' => [
- [
- 'host' => '0.0.0.0',
- 'port' => 5292,
- 'type' => SWOOLE_SOCK_UDP,
- 'settings' => [
- 'open_eof_check' => true,
- 'package_eof' => "\r\n",
- ],
- 'handler' => \App\Sockets\TestUdpSocket::class,
- ],
- ],
- Http
- 'sockets' => [
- [
- 'host' => '0.0.0.0',
- 'port' => 5293,
- 'type' => SWOOLE_SOCK_TCP,
- 'settings' => [
- 'open_http_protocol' => true,
- ],
- 'handler' => \App\Sockets\TestHttp::class,
- ],
- ],
- WebSocket:主服务器必须
开启WebSocket
,即需要将websocket.enable
置为true
。
- 'sockets' => [
- [
- 'host' => '0.0.0.0',
- 'port' => 5294,
- 'type' => SWOOLE_SOCK_TCP,
- 'settings' => [
- 'open_http_protocol' => true,
- 'open_websocket_protocol' => true,
- ],
- 'handler' => \App\Sockets\TestWebSocket::class,
- ],
- ],