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
版权声明:本文标题:tp6 think 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.roclinux.cn/b/1693763386a241410.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论