WebSocket Server

1.框架提供原始的 FastD\Servitization\Server,实现代码如下:

  1. <?php
  2. class WebSocketServer extends WebSocket
  3. {
  4. use OnWorkerStart;
  5. /**
  6. * @param swoole_server $server
  7. * @param swoole_websocket_frame $frame
  8. *
  9. * @return int|mixed
  10. *
  11. * @throws \Exception
  12. * @throws \FastD\Packet\Exceptions\PacketException
  13. */
  14. public function doMessage(swoole_server $server, swoole_websocket_frame $frame)
  15. {
  16. $data = $frame->data;
  17. $data = Json::decode($data);
  18. $request = new ServerRequest($data['method'], $data['path']);
  19. if (isset($data['args'])) {
  20. if ('GET' === $request->getMethod()) {
  21. $request->withQueryParams($data['args']);
  22. } else {
  23. $request->withParsedBody($data['args']);
  24. }
  25. }
  26. $response = app()->handleRequest($request);
  27. $fd = null !== ($fd = $response->getFileDescriptor()) ? $fd : $frame->fd;
  28. if (false === $server->connection_info($fd)) {
  29. return -1;
  30. }
  31. $server->push($fd, (string) $response->getBody());
  32. app()->shutdown($request, $response);
  33. return 0;
  34. }
  35. }
  36. 配置文件
  37. return [
  38. 'host' => 'ws://127.0.0.1:9527',
  39. 'class' => \FastD\Servitization\Server\WebSocketServer::class,
  40. 'options' => [
  41. 'pid_file' => __DIR__.'/../runtime/pid/'.app()->getName().'.pid',
  42. 'log_file' => __DIR__.'/../runtime/logs/'.date('Ymd').'/'.app()->getName().'.log',
  43. 'worker_num' => 8,
  44. 'task_worker_num' => 8,
  45. 'user' => 'www',
  46. 'group' => 'www',
  47. ],
  48. ];

主要核心接受 json 格式数据,由 FastD\Packet\Json 对象进行处理。因此 TCPServer 接受需要接受 json 格式的数据,例如:

  1. {
  2. "method":"POST",
  3. "path": "/",
  4. "args": [
  5. "foo":"bar"
  6. ]
  7. }

客户端示例代码:

  1. var ws = new WebSocket("ws://127.0.0.1:9527");
  2. ws.onopen = function(evt) {
  3. console.log("Connection open ...");
  4. var data = {
  5. "method":"POST",
  6. "path":"/",
  7. "args":{
  8. "foo":"bar"
  9. }
  10. };
  11. data = JSON.stringify(data);
  12. ws.send(data);
  13. };
  14. ws.onmessage = function(evt) {
  15. console.log("Received Message: " + evt.data);
  16. ws.close();
  17. };
  18. ws.onclose = function(evt) {
  19. console.log("Connection closed.");
  20. };

如上示例会被分发到POST路由 "/" 下,参数foo值为bar

2.如果你想自定义WebSocket 只需要修改配置为

  1. return [
  2. 'host' => 'ws://127.0.0.1:9527',
  3. 'class' => \Server\CustomizeSocketServer::class,
  4. 'options' => [
  5. 'pid_file' => __DIR__.'/../runtime/pid/'.app()->getName().'.pid',
  6. 'log_file' => __DIR__.'/../runtime/logs/'.date('Ymd').'/'.app()->getName().'.log',
  7. 'worker_num' => 8,
  8. 'task_worker_num' => 8,
  9. 'user' => 'www',
  10. 'group' => 'www',
  11. ],
  12. ];

并增加目录和文件:项目目录/app/src/Server/CustomizeSocketServer.php 大致内容如下:

  1. <?php
  2. namespace Server;
  3. use FastD\Servitization\OnWorkerStart;
  4. use FastD\Swoole\Server\WebSocket;
  5. use swoole_server;
  6. use swoole_websocket_frame;
  7. /**
  8. * Class WebSocketServer.
  9. */
  10. class CustomizeSocketServer extends WebSocket
  11. {
  12. use OnWorkerStart;
  13. /**
  14. * @param swoole_server $server
  15. * @param swoole_websocket_frame $frame
  16. *
  17. * @return int|mixed
  18. *
  19. * @throws \Exception
  20. * @throws \FastD\Packet\Exceptions\PacketException
  21. */
  22. public function doMessage(swoole_server $server, swoole_websocket_frame $frame)
  23. {
  24. //接收客户端的数据 $frame-data
  25. //客户链接标识: $frame->fd
  26. //在这里实现你的代码逻辑
  27. //如想直接响应客户端(如果响应的数据为二进制数据需要增加第三个参数为 WEBSOCKET_OPCODE_BINARY )
  28. $server->push($frame->fd, "hello!");
  29. }
  30. public function doClose(swoole_server $server, $fd, $fromId){
  31. //客户端断开事件
  32. }
  33. //还有其他事件请看 WebSocket 类
  34. }

启动服务 :cd到项目目录执行 php bin/server start 如需挂为守护进程增加 -d 参数