您现在的位置是:首页 > 博客日记 > Php Php

用thinkphp6框架的think-swoole实现websocket的onRequest回调事件

2020-04-20 12:36:55 【Php】 人已围观

用thinkphp6框架的think-swoole实现websocket的onRequest回调事件

为什么要写这个onRequest回调
1.用户链接socket后发送消息触发对应消息相应并回复 satisfy
2.用户链接socket后 我们在后台主动触发按钮调用接口去主动发送给指定用户 no satisfy
so,我们修改以下代码.

1.修改thinkphp6的底层类vendor/topthink/think-swoole/src/concerns/InteractsWithHttp.php第96行
  1. /**
  2. * "onRequest" listener.
  3. *
  4. * @param Request $req
  5. * @param Response $res
  6. */
  7. public function onRequest($req, $res)
  8. {
  9. /**
  10. * TinyMeng update start
  11. */
  12. $httpRequest = config("swoole.websocket.httpRequest");
  13. if(!empty($httpRequest)){
  14. if(isset($req->get['websocket'])){
  15. $websocket = new $httpRequest($this->getServer());
  16. return $websocket->onRequest($req,$res);
  17. }else{
  18. //return true;
  19. }
  20. }
  21. /** Tinymeng end */
  22. $args = func_get_args();
  23. $this->runInSandbox(function (Http $http, Event $event, App $app, Middleware $middleware) use ($args, $req, $res) {
  24. $event->trigger('swoole.request', $args);
  25. //兼容var-dumper
  26. if (class_exists(VarDumper::class)) {
  27. $middleware->add(ResetVarDumper::class);
  28. }
  29. $request = $this->prepareRequest($req);
  30. try {
  31. $response = $this->handleRequest($http, $request);
  32. } catch (Throwable $e) {
  33. $response = $this->app
  34. ->make(Handle::class)
  35. ->render($request, $e);
  36. }
  37. $this->sendResponse($res, $response, $app->cookie);
  38. });
  39. }
2.修改配置文件 config\swoole.php
  1. <?php
  2. use app\common\service\swoole\WebsocketMessage;
  3. use app\common\service\swoole\SocketHandler;
  4. use think\swoole\websocket\socketio\Parser;
  5. return [
  6. 'server' => [
  7. 'host' => env('SWOOLE_HOST', '127.0.0.1'), // 监听地址127.0.0.1
  8. 'port' => env('SWOOLE_PORT', 9502), // 监听端口
  9. 'mode' => SWOOLE_PROCESS, // 运行模式 默认为SWOOLE_PROCESS
  10. 'sock_type' => SWOOLE_SOCK_TCP, // sock type 默认为SWOOLE_SOCK_TCP
  11. 'options' => [
  12. 'pid_file' => runtime_path() . 'swoole.pid',
  13. 'log_file' => runtime_path() . 'swoole.log',
  14. 'daemonize' => true,//守护进程方式运行
  15. // Normally this value should be 1~4 times larger according to your cpu cores.
  16. 'reactor_num' => swoole_cpu_num(),
  17. 'worker_num' => swoole_cpu_num(),
  18. 'task_worker_num' => swoole_cpu_num(),
  19. 'enable_static_handler' => true,
  20. 'document_root' => root_path('public'),
  21. 'package_max_length' => 20 * 1024 * 1024,
  22. 'buffer_output_size' => 10 * 1024 * 1024,
  23. 'socket_buffer_size' => 128 * 1024 * 1024,
  24. ],
  25. ],
  26. 'websocket' => [
  27. 'enable' => true,
  28. 'handler' => SocketHandler::class,//SocketHandler
  29. 'httpRequest' => WebsocketMessage::class,//监听onRequest回调
  30. 'parser' => Parser::class,
  31. 'ping_interval' => 25000,
  32. 'ping_timeout' => 60000,
  33. 'room' => [],
  34. 'listen' => [],
  35. 'subscribe' => [],
  36. ],
  37. //热更新
  38. 'hot_update' => [
  39. 'enable' => env('APP_DEBUG', false),
  40. 'name' => ['*.php'],
  41. 'include' => [app_path(),config_path()],
  42. 'exclude' => [],
  43. ],
  44. ];
3.监听用户SocketHandler触发 app\common\service\swoole\SocketHandler
  1. <?php
  2. namespace app\common\service\swoole;
  3. use Swoole\Server;
  4. use think\Config;
  5. use think\Request;
  6. use Swoole\Websocket\Frame;
  7. use app\common\service\CommonService;
  8. use think\swoole\contract\websocket\HandlerInterface;
  9. class SocketHandler implements HandlerInterface
  10. {
  11. /** @var Websocket */
  12. protected $websocket;
  13. /** @var Config */
  14. protected $config;
  15. /**
  16. * SocketHandler constructor.
  17. * @Author: TinyMeng <666@majiameng.com>
  18. * @param \Swoole\Server $server
  19. * @param Config $config
  20. */
  21. public function __construct(Server $server, Config $config)
  22. {
  23. $this->config = $config;
  24. }
  25. /**
  26. * 监听用户连接事件
  27. * @Author: TinyMeng <666@majiameng.com>
  28. * @param int $fd
  29. * @param Request $request
  30. */
  31. public function onOpen($fd, Request $request){
  32. CommonService::writeLog("fd:".$fd."连接");
  33. }
  34. /**
  35. * 监听用户断开事件
  36. * @Author: TinyMeng <666@majiameng.com>
  37. * @param int $fd
  38. * @param int $reactorId
  39. * @return bool
  40. * @throws \think\db\exception\DataNotFoundException
  41. * @throws \think\db\exception\DbException
  42. * @throws \think\db\exception\ModelNotFoundException
  43. */
  44. public function onClose($fd, $reactorId){
  45. CommonService::writeLog("fd:".$fd."断开");
  46. return true;
  47. }
  48. /**
  49. * 监听用户message事件
  50. * @Author: TinyMeng <666@majiameng.com>
  51. * @param Frame $frame
  52. * @return bool
  53. */
  54. public function onMessage(Frame $frame){
  55. $packet = trim($frame->data);
  56. CommonService::writeLog("onMessage:".$packet.".");
  57. return true;
  58. }
  59. }
4.监听onRequest回调,程序主动触发给用户 app\common\service\swoole\WebsocketMessage
  1. <?php
  2. namespace app\common\service\swoole;
  3. use Swoole\Websocket\Frame;
  4. use Swoole\WebSocket\Server;
  5. class WebsocketMessage extends Websocket
  6. {
  7. /**
  8. * \Swoole\Server
  9. * @Author: TinyMeng <666@majiameng.com>
  10. * Websocket constructor.
  11. * @param Server $server
  12. */
  13. public function __construct(Server $server)
  14. {
  15. parent::__construct($server);
  16. }
  17. /**
  18. * onRequest回调
  19. * //127.0.0.1:9502/?websocket=1&action=ONLINEADD&packet=
  20. * @Author: TinyMeng <666@majiameng.com>
  21. * @param $req
  22. * @param $respone
  23. */
  24. public function onRequest($req, $respone){
  25. if (!empty($req->get['packet'])) {
  26. CommonService::writeLog("onRequest:".$req->get['packet'].".");
  27. }
  28. $respone->end("success");
  29. }
  30. }

5.主动触发发送

  1. use tinymeng\tools\HttpRequest;
  2. try{
  3. $url = "//127.0.0.1:9502/";
  4. $packet_array = [
  5. 'websocket'=>1,
  6. 'trigger'=>1,
  7. 'packet'=>json_encode($data),//发送的消息内容
  8. ];
  9. HttpRequest::httpGet($url,$packet_array);
  10. }catch (\Exception $exception){
  11. ExceptionHandle::sendErrorEmail($exception);
  12. return false;
  13. }


关注TinyMeng博客,更多精彩分享,敬请期待!
 

很赞哦! ()