多端口混合协议

更多的信息,请参考Swoole增加监听的端口多端口混合协议

为了使我们的主服务器能支持除HTTPWebSocket外的更多协议,我们引入了Swoole多端口混合协议特性,在LaravelS中称为Socket。现在,可以很方便地在Laravel上被构建TCP/UDP应用。

  • 创建Socket处理类,继承Hhxsv5\LaravelS\Swoole\Socket{TcpSocket|UdpSocket|Http|WebSocket}
  1. namespace App\Sockets;
  2. use Hhxsv5\LaravelS\Swoole\Socket\TcpSocket;
  3. use Swoole\Server;
  4. class TestTcpSocket extends TcpSocket
  5. {
  6. public function onConnect(Server $server, $fd, $reactorId)
  7. {
  8. \Log::info('New TCP connection', [$fd]);
  9. $server->send($fd, 'Welcome to LaravelS.');
  10. }
  11. public function onReceive(Server $server, $fd, $reactorId, $data)
  12. {
  13. \Log::info('Received data', [$fd, $data]);
  14. $server->send($fd, 'LaravelS: ' . $data);
  15. if ($data === "quit\r\n") {
  16. $server->send($fd, 'LaravelS: bye' . PHP_EOL);
  17. $server->close($fd);
  18. }
  19. }
  20. public function onClose(Server $server, $fd, $reactorId)
  21. {
  22. \Log::info('Close TCP connection', [$fd]);
  23. $server->send($fd, 'Goodbye');
  24. }
  25. }

这些连接和主服务器上的HTTP/WebSocket连接共享Worker进程,因此可以在这些事件操作中使用LaravelS提供的异步任务投递SwooleTable、Laravel提供的组件如DBEloquent等。同时,如果需要使用该协议端口的Swoole\Server\Port对象,只需要像如下代码一样访问Socket类的成员swoolePort即可。

  1. public function onReceive(Server $server, $fd, $reactorId, $data)
  2. {
  3. $port = $this->swoolePort; //获得`Swoole\Server\Port`对象
  4. }
  • 注册套接字。
  1. // 修改文件 config/laravels.php
  2. // ...
  3. 'sockets' => [
  4. [
  5. 'host' => '127.0.0.1',
  6. 'port' => 5291,
  7. 'type' => SWOOLE_SOCK_TCP,// 支持的嵌套字类型:https://wiki.swoole.com/wiki/page/16.html#entry_h2_0
  8. 'settings' => [// Swoole可用的配置项:https://wiki.swoole.com/wiki/page/526.html
  9. 'open_eof_check' => true,
  10. 'package_eof' => "\r\n",
  11. ],
  12. 'handler' => \App\Sockets\TestTcpSocket::class,
  13. ],
  14. ],

关于心跳配置,只能设置在主服务器上,不能配置在套接字上,但套接字会继承主服务器的心跳配置。

对于TCP协议,dispatch_mode选项设为1/3时,底层会屏蔽onConnect/onClose事件,原因是这两种模式下无法保证onConnect/onClose/onReceive的顺序。如果需要用到这两个事件,请将dispatch_mode改为2/4/5参考

  1. 'swoole' => [
  2. //...
  3. 'dispatch_mode' => 2,
  4. //...
  5. ];
  • 测试。

  • TCP:telnet 127.0.0.1 5291

  • UDP:Linux下 echo "Hello LaravelS" > /dev/udp/127.0.0.1/5292

  • 其他协议的注册示例。

    • UDP
  1. 'sockets' => [
  2. [
  3. 'host' => '0.0.0.0',
  4. 'port' => 5292,
  5. 'type' => SWOOLE_SOCK_UDP,
  6. 'settings' => [
  7. 'open_eof_check' => true,
  8. 'package_eof' => "\r\n",
  9. ],
  10. 'handler' => \App\Sockets\TestUdpSocket::class,
  11. ],
  12. ],
  • Http
  1. 'sockets' => [
  2. [
  3. 'host' => '0.0.0.0',
  4. 'port' => 5293,
  5. 'type' => SWOOLE_SOCK_TCP,
  6. 'settings' => [
  7. 'open_http_protocol' => true,
  8. ],
  9. 'handler' => \App\Sockets\TestHttp::class,
  10. ],
  11. ],
  • WebSocket:主服务器必须开启WebSocket,即需要将websocket.enable置为true
  1. 'sockets' => [
  2. [
  3. 'host' => '0.0.0.0',
  4. 'port' => 5294,
  5. 'type' => SWOOLE_SOCK_TCP,
  6. 'settings' => [
  7. 'open_http_protocol' => true,
  8. 'open_websocket_protocol' => true,
  9. ],
  10. 'handler' => \App\Sockets\TestWebSocket::class,
  11. ],
  12. ],