admin 管理员组

文章数量: 1184232

tp6 think

我使用时的环境

Centos 7.9
PHP 7.4
Swoole	4.8.5
thinkPHP6 6.0.8
think-swoole 4.0

问题描述:socket.io与服务器连接成功,但是服务器没有根据客户端发的请求去执行,没有任何的返回,根本就没执行到listen中写的行为

网上的例子找了不少,其实网上也没几个,都试了一下,代码基本都是大同小异,但是我试的时候就是跑不起来,只要在config/swoole.php配置文件中开启了websocket,连接是成功的,但是就是没有返回,直到看到了这篇文章【think-swoole4.0.4 websocket 使用(追梦人)】,照着里面的例子,客户端终于能接收到数据了。我寻思着这是为啥呢?他的config/swoole.php中listen中的配置如下。

于是我照葫芦画瓢也复制了一条例子,在他下面新加了一条记录,结果又是不行?这我就emo了呀。加了交流群,但是没人鸟我,没办法了,只能翻他的源码了,一路从入口文件往下翻,终于在代码中发现了原因。在源码中只触发了swoole.websocket.Event的监听行为

文件位置:vendor/topthink/think-swoole/src/websocket/socketio/Handler.php


在他的源码中,当触发了onMessage事件时,它只触发了’swoole.websocket.Event’事件(这个事件名称为什么长成这样,跟config/swoole.php中不一样,是因为他在建立构建websocket服务的时候,会把在config/swoole.php中listen中写的参数转换成这样的形式。因为这个行为是依靠tp6中event来实现的,所以也可以直接在app/event.php中直接按照这样的形式写),不懂他为什么不写成通用的方式,现在这样写的话,,看他传入了$type(方法名),$data(客户端传递的参数)这些数据,就是说其实利用的就只是那一个监听行为,你自己在app\listener\WebsocketEvent.php中handler函数中去根据$type去判断要执行那个方法喽。只有一个监听行为,是不是可以不卡一些,然后运行的快一点??

我尝试着把此处的代码改成了这样,只要改成这样网上哪些例子就都能跑了,这样在config/swoole.php中配置的listen中填的那些行为。在客户端中触发哪个就走那个。

$result = $this->event->trigger('swoole.websocket.'.Str::studly($type), new WsEvent($type, $data));

不过我不建议这么改,因为我也不懂为什么不这样写,但是他现在的写法一定有道理,还是按他的来吧。而且改插件源码什么的,不合适!

代码

config\swoole.php
<?phpuse think\swoole\websocket\socketio\Handler;return ['http'       => ['enable'     => true,'host'       => '0.0.0.0','port'       => 8998,'worker_num' => swoole_cpu_num(),'options'    => [],],'websocket'  => ['enable'        => true,'handler'       => Handler::class,'ping_interval' => 25000,'ping_timeout'  => 60000,'room'          => ['type'  => 'table','table' => ['room_rows'   => 8192,'room_size'   => 2048,'client_rows' => 4096,'client_size' => 2048,],'redis' => ['host'          => '127.0.0.1','port'          => 6379,'max_active'    => 3,'max_wait_time' => 5,],],'listen'        => ['event' => \app\listener\WebsocketEvent::class,'test' => \app\listener\WebsocketTest::class],'subscribe'     => [],],'rpc'        => ['server' => ['enable'     => false,'host'       => '0.0.0.0','port'       => 9000,'worker_num' => swoole_cpu_num(),'services'   => [],],'client' => [],],//队列'queue'      => ['enable'  => false,'workers' => [],],'hot_update' => ['enable'  => env('APP_DEBUG', false),'name'    => ['*.php'],'include' => [app_path()],'exclude' => [],],//连接池'pool'       => ['db'    => ['enable'        => true,'max_active'    => 3,'max_wait_time' => 5,],'cache' => ['enable'        => true,'max_active'    => 3,'max_wait_time' => 5,],//自定义连接池],'tables'     => [],//每个worker里需要预加载以共用的实例'concretes'  => [],//重置器'resetters'  => [],//每次请求前需要清空的实例'instances'  => [],//每次请求前需要重新执行的服务'services'   => [],
];
app\listener\WebsocketEvent.php
<?php
declare (strict_types = 1);namespace app\listener;
use think\Container;
use think\swoole\Websocket;
class WebsocketEvent
{public $websocket = null;public function __construct(Container $container) {$this->websocket = $container->make(Websocket::class);}/*** 事件监听处理** @return mixed*/public function handle($event){echo "Event\n";$func = $event->type; // 要调用的方法if (!method_exists($this, $func)) {$this->websocket->emit('testcallback', ['msg'=> $func.':方法不存在']);} else {$this->$func($event);}}/*** 测试类型* @param $event*/public function test($event){$this->websocket->emit('testcallback', ['aaaaa' => 1, 'getdata' => '123123']);}
}
~      
app\listener\WebsocketTest.php
<?php
declare (strict_types = 1);namespace app\listener;
use think\Container;
use think\swoole\Websocket;
class WebsocketTest
{public $websocket = null;public function __construct(Container $container) {$this->websocket = $container->make(Websocket::class);}/*** 事件监听处理** @return mixed*/public function handle($event){$this->websocket->emit("testcallback", ['msg'=> '来自listen-test的数据返回']);}
}
html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src=".io-1.4.4.js"></script><script src=".11.1.js"></script>
</head>
<body><div><div>返回内容:</div><div style="width: 600px;height: 600px" id="content"></div>
</div>
<div>在控制台中执行 socket.emit("test",{"asd":"我是内容"})
</div>
<div>在控制台中执行 socket.emit("join",{"room":"roomtest"})  加入房间
</div>
<div>在控制台中执行 socket.emit("leave",{"room":["roomtest"]})  离开房间
</div>
<script>var  socket = io(':8998',{transports: ['websocket']});//xxx 这个自己替换成自己的环境thinkphp-swoole 的端口或者是nginx的代理端口//transports: ['websocket'] 一定要这个,改为websocket链接//polling 这个不支持,轮询会导致请求变成http请求,post请求全部拒接掉socket.emit('test',{"asd":"asd"});//自定义msg事件,发送‘你好服务器’字符串向服务器socket.on('testcallback',(data)=>{//监听浏览器通过msg事件发送的信息console.log('服务器返回的数据:', data);//你好浏览器});socket.emit('join',{"asd":"asd"});socket.on('roomJoin',(data)=>{console.log(data);//你好浏览器})
</script>
</body>
</html>

本文标签: tp6 think