websocket 控制器

在根据上两章安装配置好之后,就可以在 app/WebSocket 下创建需要的 websocket 控制器来处理相关逻辑

说明

注解tag

websocket 新增了类注解tag @WebSocket

  • 说明
  1. /**
  2. * @WebSocket("/echo")
  3. */

上面的注解标明了允许ws连接的URI path. 即客户端请求的ws连接类似: ws://IP:PORT/echo

创建控制器类

可以通过命令 php bin/swoft gen:websocket 来快速创建一个控制器。

  1. php bin/swoft gen:websocket echo --prefix /echo

事件处理

在每个控制器里允许用户处理的几个事件有 handshake open message close

处理握手 handshake

通过方法 checkHandshake 可以对客户端的握手请求进行处理。 比如 验证token,domian … 等

这方法是可选的。如果没有特殊的需求,可以忽略它,框架会帮你握手并响应握手成功。

checkHandshake 必须返回含有两个元素的array

  • 第一个元素的值来决定是否进行握手
  • 第二个元素是response对象 - 可以在response设置一些自定义header,body等信息

连接打开 open

在握手成功后,就会触发 open 事件,此时开始你就可以给客户端发消息了 :)

注意

  • 此方法也是可选的,可以没有
  • onOpen 是swoft在握手后通过 $server->defer() 来触发的,没有在协程环境中。

接收消息 message

通过控制器的方法 onMessage 你可以接收到客户端的消息和发送消息给对方. 此方法是必须存在的

连接关闭 close

当客户的关闭连接或者server在其他地方主动关闭连接时,就会触发此事件。

你可以在这里做一些连接关闭后的工作, 比如:记录日志,解绑用户等 …

  • 此方法也是可选的,可以没有

注意:触发此事件时连接已被关闭,不能再给对方发消息

代码示例

  • 这里面方法上的 server 对象都是 Swoole\WebSocket\Server 的实例
  1. <?php
  2. namespace App\WebSocket;
  3. use Swoft\Http\Message\Server\Request;
  4. use Swoft\Http\Message\Server\Response;
  5. use Swoft\WebSocket\Server\Bean\Annotation\WebSocket;
  6. use Swoft\WebSocket\Server\HandlerInterface;
  7. use Swoole\WebSocket\Frame;
  8. use Swoole\WebSocket\Server;
  9. /**
  10. * Class EchoController
  11. * @package App\WebSocket
  12. * @WebSocket("/echo")
  13. */
  14. class EchoController implements HandlerInterface
  15. {
  16. /**
  17. * 在这里你可以验证握手的请求信息
  18. * - 必须返回含有两个元素的array
  19. * - 第一个元素的值来决定是否进行握手
  20. * - 第二个元素是response对象
  21. * - 可以在response设置一些自定义header,body等信息
  22. * @param Request $request
  23. * @param Response $response
  24. * @return array
  25. * [
  26. * self::HANDSHAKE_OK,
  27. * $response
  28. * ]
  29. */
  30. public function checkHandshake(Request $request, Response $response): array
  31. {
  32. return [self::HANDSHAKE_OK, $response];
  33. }
  34. /**
  35. * @param Server $server
  36. * @param Request $request
  37. * @param int $fd
  38. */
  39. public function onOpen(Server $server, Request $request, int $fd)
  40. {
  41. $server->push($fd, 'hello, welcome! :)');
  42. }
  43. /**
  44. * @param Server $server
  45. * @param Frame $frame
  46. */
  47. public function onMessage(Server $server, Frame $frame)
  48. {
  49. $server->push($frame->fd, 'I have received message: ' . $frame->data);
  50. }
  51. /**
  52. * on connection closed
  53. * @param Server $server
  54. * @param int $fd
  55. */
  56. public function onClose(Server $server, int $fd)
  57. {
  58. // you can do something. eg. record log, unbind user...
  59. }
  60. }

客户端测试

如果你安装并启用了 devtool, 那么你可以打开页面 IP:PORT/__devtool/ws/test 来进行ws测试

  • 填上你的ws server地址(注意不要忘了URI path)
  • 然后就可以连接上ws server 并收发消息了
  • 如果你在前台运行的server 你也能在运行 server的console 上看到ws连接与消息log

效果截图:

ws-test-page

当然也可在网上找一个 ws test网页来进行测试