用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行
/**
* "onRequest" listener.
*
* @param Request $req
* @param Response $res
*/
public function onRequest($req, $res)
{
/**
* TinyMeng update start
*/
$httpRequest = config("swoole.websocket.httpRequest");
if(!empty($httpRequest)){
if(isset($req->get['websocket'])){
$websocket = new $httpRequest($this->getServer());
return $websocket->onRequest($req,$res);
}else{
//return true;
}
}
/** Tinymeng end */
$args = func_get_args();
$this->runInSandbox(function (Http $http, Event $event, App $app, Middleware $middleware) use ($args, $req, $res) {
$event->trigger('swoole.request', $args);
//兼容var-dumper
if (class_exists(VarDumper::class)) {
$middleware->add(ResetVarDumper::class);
}
$request = $this->prepareRequest($req);
try {
$response = $this->handleRequest($http, $request);
} catch (Throwable $e) {
$response = $this->app
->make(Handle::class)
->render($request, $e);
}
$this->sendResponse($res, $response, $app->cookie);
});
}
2.修改配置文件 config\swoole.php
<?php
use app\common\service\swoole\WebsocketMessage;
use app\common\service\swoole\SocketHandler;
use think\swoole\websocket\socketio\Parser;
return [
'server' => [
'host' => env('SWOOLE_HOST', '127.0.0.1'), // 监听地址127.0.0.1
'port' => env('SWOOLE_PORT', 9502), // 监听端口
'mode' => SWOOLE_PROCESS, // 运行模式 默认为SWOOLE_PROCESS
'sock_type' => SWOOLE_SOCK_TCP, // sock type 默认为SWOOLE_SOCK_TCP
'options' => [
'pid_file' => runtime_path() . 'swoole.pid',
'log_file' => runtime_path() . 'swoole.log',
'daemonize' => true,//守护进程方式运行
// Normally this value should be 1~4 times larger according to your cpu cores.
'reactor_num' => swoole_cpu_num(),
'worker_num' => swoole_cpu_num(),
'task_worker_num' => swoole_cpu_num(),
'enable_static_handler' => true,
'document_root' => root_path('public'),
'package_max_length' => 20 * 1024 * 1024,
'buffer_output_size' => 10 * 1024 * 1024,
'socket_buffer_size' => 128 * 1024 * 1024,
],
],
'websocket' => [
'enable' => true,
'handler' => SocketHandler::class,//SocketHandler
'httpRequest' => WebsocketMessage::class,//监听onRequest回调
'parser' => Parser::class,
'ping_interval' => 25000,
'ping_timeout' => 60000,
'room' => [],
'listen' => [],
'subscribe' => [],
],
//热更新
'hot_update' => [
'enable' => env('APP_DEBUG', false),
'name' => ['*.php'],
'include' => [app_path(),config_path()],
'exclude' => [],
],
];
3.监听用户SocketHandler触发 app\common\service\swoole\SocketHandler
<?php
namespace app\common\service\swoole;
use Swoole\Server;
use think\Config;
use think\Request;
use Swoole\Websocket\Frame;
use app\common\service\CommonService;
use think\swoole\contract\websocket\HandlerInterface;
class SocketHandler implements HandlerInterface
{
/** @var Websocket */
protected $websocket;
/** @var Config */
protected $config;
/**
* SocketHandler constructor.
* @Author: TinyMeng <666@majiameng.com>
* @param \Swoole\Server $server
* @param Config $config
*/
public function __construct(Server $server, Config $config)
{
$this->config = $config;
}
/**
* 监听用户连接事件
* @Author: TinyMeng <666@majiameng.com>
* @param int $fd
* @param Request $request
*/
public function onOpen($fd, Request $request){
CommonService::writeLog("fd:".$fd."连接");
}
/**
* 监听用户断开事件
* @Author: TinyMeng <666@majiameng.com>
* @param int $fd
* @param int $reactorId
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function onClose($fd, $reactorId){
CommonService::writeLog("fd:".$fd."断开");
return true;
}
/**
* 监听用户message事件
* @Author: TinyMeng <666@majiameng.com>
* @param Frame $frame
* @return bool
*/
public function onMessage(Frame $frame){
$packet = trim($frame->data);
CommonService::writeLog("onMessage:".$packet.".");
return true;
}
}
4.监听onRequest回调,程序主动触发给用户 app\common\service\swoole\WebsocketMessage
<?php
namespace app\common\service\swoole;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server;
class WebsocketMessage extends Websocket
{
/**
* \Swoole\Server
* @Author: TinyMeng <666@majiameng.com>
* Websocket constructor.
* @param Server $server
*/
public function __construct(Server $server)
{
parent::__construct($server);
}
/**
* onRequest回调
* //127.0.0.1:9502/?websocket=1&action=ONLINEADD&packet=
* @Author: TinyMeng <666@majiameng.com>
* @param $req
* @param $respone
*/
public function onRequest($req, $respone){
if (!empty($req->get['packet'])) {
CommonService::writeLog("onRequest:".$req->get['packet'].".");
}
$respone->end("success");
}
}
5.主动触发发送
use tinymeng\tools\HttpRequest;
try{
$url = "//127.0.0.1:9502/";
$packet_array = [
'websocket'=>1,
'trigger'=>1,
'packet'=>json_encode($data),//发送的消息内容
];
HttpRequest::httpGet($url,$packet_array);
}catch (\Exception $exception){
ExceptionHandle::sendErrorEmail($exception);
return false;
}
4 comments
有问题的话可以直接在下面留言
6666666666666666666666666
这次我把代码补全了,很easy
呕吼 能看懂的人很少哦