ThinkPHP8使用workerman

ops/2024/11/25 14:23:10/

应用场景说明:通过建立通信,不同用户进行消息推送或数据更新,因为本身需要作为服务端进行主动消息推送,因此使用Gateway方式,如果不需要的可以不采用这种形式,以下内容仅为参考,具体业务场景,自行修改!!!!

Linux或MacOS不需要进行自定义命令,直接使用php think worker:server  php think worker:gateway 使用即可。

废话少说,直接开干!!!

你可能会碰到以下问题,仅供参考!

一、可能会出现问题

1.GatewayWorker Not Support On Windows.

此问题出现在启用命令php think worker:gateway之后,需要使用自定义命令进行修改,具体下面细说

2.Implicit conversion from float 999996.9005584717 to int loses precision

此问题,在自定义命令后,需进行如下修改:\vendor\workerman\workerman\Events\Selelct.php第215行,

usleep($this->_selectTimeout); //    修改为下面usleep((int)$this->_selectTimeout);
二、不使用gateway

1.安装think-worker

composer require topthink/think-worker

2.运行命令

php think worker 运行httpphp think worker:server 运行webscoket //    默认是2345端口 

3.测试链接

// 新建一个html,直接复制以下代码,浏览器访问,打开控制台
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
</body>
<script>/*** 与GatewayWorker建立websocket连接,域名和端口改为你实际的域名端口,* 其中端口为Gateway端口,即start_gateway.php指定的端口。* start_gateway.php 中需要指定websocket协议,像这样* $gateway = new Gateway(websocket://0.0.0.0:7272);*/ws = new WebSocket("ws://127.0.0.1:2348");// 服务端主动推送消息时会触发这里的onmessagews.onopen = function () {// 触发系统自定义的test_event事件,发送json数据var data = {"type": "bind", "data": {"uid": "10001"}};ws.send(JSON.stringify(data));}ws.onmessage = function (e) {console.log(e.data);var data = {"type": "send", "data": {"uid": "10001", 'message': '呦吼'}};ws.send(JSON.stringify(data))}// ws.onmessage = onmessagews.onclose = function () {//  连接关闭,推送消息至服务端var data = {type: 'close', data: "{'uid':10001}"};ws.send(JSON.stringify(data));}</script>
</html>

4、效果截图

监听的方法,默认在config/worker_server.php里面,也可以通过继承Server进行修改,具体方法参考手册。tp-workerman
tps://i-blog.csdnimg.cn/direct/824412d81d184ab8877219bd5ee0e2b6.png" width="799" />

tps://i-blog.csdnimg.cn/direct/8112eec43042479898ad3eec815cb756.png" width="1200" />

三、使用Gateway

如果直接使用 php think worker:gateway 就会提示GatewayWorker Not Support On Windows.具体原因简单说明(php think worker:gateway就是在同一个php文件里启动了多个worker,因为不能成功运行所以tp的命令行提前做了判定,显示不支持在windows下运行),大家自行搜一下具体原因即可。

具体解决思路,自定义命令进行运行,根据以下步骤进行参考

1.创建命令

php think make:command common@WorkerMain

2.复制以下代码到以上文件中

<?phpnamespace app\common\command;use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Config;
use Workerman\Worker;/*** Worker 命令行*/
class WorkerMain extends Command
{public function configure(){$this->setName('WorkerMain')->addArgument('service', Argument::OPTIONAL, 'workerman service: gateway|register|business_worker', null)->addOption('host', 'H', Option::VALUE_OPTIONAL, 'the host of workerman server.', null)->addOption('port', 'p', Option::VALUE_OPTIONAL, 'the port of workerman server.', null)->setDescription('GatewayWorker Server for ThinkPHP runs on Windows system');}/*** 由于windows下不支持下无法使用status、stop、reload、restart等命令。* 所以去掉status、stop、reload、restart、守护进程等命令。* 文档说明: https://www.workerman.net/doc/workerman/must-read.html** 命令使用:* php think worker:gateway_win register* php think worker:gateway_win business_worker* php think worker:gateway_win gateway** @param Input $input* @param Output $output* @return int|void|null*/public function execute(Input $input, Output $output){$service = $input->getArgument('service');$option = Config::get('gateway_worker');if ($input->hasOption('host')) {$host = $input->getOption('host');} else {$host = !empty($option['host']) ? $option['host'] : '0.0.0.0';}if ($input->hasOption('port')) {$port = $input->getOption('port');} else {$port = !empty($option['port']) ? $option['port'] : '2347';}$registerAddress = !empty($option['registerAddress']) ? $option['registerAddress'] : '127.0.0.1:1236';switch ($service) {case 'register':$this->register($registerAddress);break;case 'business_worker':$this->businessWorker($registerAddress, $option['businessWorker'] ?? []);break;case 'gateway':$this->gateway($registerAddress, $host, $port, $option);break;default:$output->writeln("<error>Invalid argument action:{$service}, Expected gateway|register|business_worker.</error>");exit(1);break;}Worker::runAll();}/*** 启动register* @access public* @param string $registerAddress* @return void*/public function register(string $registerAddress): void{// 初始化registernew Register('text://' . $registerAddress);}/*** 启动businessWorker* @access public* @param string $registerAddress registerAddress* @param array $option 参数* @return void*/public function businessWorker(string $registerAddress, array $option = []): void{// 初始化 bussinessWorker 进程$worker = new BusinessWorker();$this->option($worker, $option);$worker->registerAddress = $registerAddress;}/*** @note 返回Gateway对象* @param string $registerAddress 注册地址* @param string $host 服务地址* @param int $port 监听端口* @param array $option 参数* @return void*/public function gateway(string $registerAddress, string $host, int $port, array $option = []): void{// 初始化 gateway 进程if (!empty($option['socket'])) {$socket = $option['socket'];unset($option['socket']);} else {$protocol = !empty($option['protocol']) ? $option['protocol'] : 'websocket';$socket = $protocol . '://' . $host . ':' . $port;unset($option['host'], $option['port'], $option['protocol']);}$gateway = new Gateway($socket, $option['context'] ?? []);// 以下设置参数都可以在配置文件中重新定义覆盖$gateway->name = 'Gateway';$gateway->count = 4;$gateway->lanIp = '127.0.0.1';$gateway->startPort = 2000;$gateway->pingInterval = 5;$gateway->pingNotResponseLimit = 0;$gateway->pingData = '{"type":"ping"}';$gateway->registerAddress = $registerAddress;// 全局静态属性设置foreach ($option as $name => $val) {if (in_array($name, ['stdoutFile', 'daemonize', 'pidFile', 'logFile'])) {Worker::${$name} = $val;unset($option[$name]);}}$this->option($gateway, $option);}/*** 设置参数* @access protected* @param Worker $worker Worker对象* @param array $option 参数* @return void*/protected function option(Worker $worker, array $option = []){// 设置参数if (!empty($option)) {foreach ($option as $key => $val) {$worker->$key = $val;}}}
}

3.运行命令

//    需依次运行以下命令php think WorkerMain gatewayphp think WorkerMain business_workerphp think WorkerMain register

4.浏览器访问:端口需改成gateway端口,默认2348

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body></body>
<script>/*** 与GatewayWorker建立websocket连接,域名和端口改为你实际的域名端口,* 其中端口为Gateway端口,即start_gateway.php指定的端口。* start_gateway.php 中需要指定websocket协议,像这样* $gateway = new Gateway(websocket://0.0.0.0:7272);*/ws = new WebSocket("ws://127.0.0.1:2348");// 服务端主动推送消息时会触发这里的onmessagews.onopen = function () {// 触发系统自定义的test_event事件,发送json数据var data = {"type": "bind", "data": {"uid": "18317093686"}};ws.send(JSON.stringify(data));}ws.onmessage = onmessagews.onclose = function () {//  连接关闭,推送消息至服务端var data = {type: 'close', data: "{'uid':10001}"};ws.send(JSON.stringify(data));}// 服务端发来消息时function onmessage(e){console.log(e.data,123);var data = JSON.parse(e.data);switch(data['type']){// 服务端ping客户端case 'ping':ws.send('{"type":"pong"}');break;;// 登录 更新用户列表case 'login':var client_name = data['client_name'];if(data['client_list']){client_id = data['client_id'];client_name = '你';client_list = data['client_list'];}else{client_list[data['client_id']] = data['client_name'];}say(data['client_id'], data['client_name'],  client_name+' 加入了聊天室', data['time']);flush_client_list();console.log(data['client_name']+"登录成功");break;// 发言case 'say'://{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}console.log(data['msg']);break;// 用户退出 更新用户列表case 'logout'://{"type":"logout","client_id":xxx,"time":"xxx"}say(data['from_client_id'], data['from_client_name'], data['from_client_name']+' 退出了', data['time']);delete client_list[data['from_client_id']];flush_client_list();}}
</script>
</html>

完成以上工作就可以顺利进行啦。


http://www.ppmy.cn/ops/136587.html

相关文章

介绍一下strlwr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strlwr(arr)&#xff1b;函数是把arr数组变为小写字母 格式 #include<string.h> strlwr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…

【Linux】进程替换

进程替换 一、概念二、原理三、替换函数1. execl2. execlp3.execle4.execv5.execvp6.execvpe 四、实现一个简易的shell 一、概念 当我们fork()生成子进程后&#xff0c;子进程的代码与数据可以来自其他可执行程序。把磁盘上其他程序的数据以覆盖的形式给子进程。这样子进程就可…

Docker 数据卷 和 挂载 的区别

在 Docker 中&#xff0c;数据卷&#xff08;Volumes&#xff09;和 挂载&#xff08;Mounts&#xff09;是两种存储和管理容器数据的方式&#xff0c;它们都可以用来持久化容器的数据&#xff0c;但它们之间有一些区别。具体来说&#xff1a; 数据卷 (Volumes) 数据卷是 Dock…

摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现

随着科技的不断进步&#xff0c;摄像机视频分析软件的发展已经为我们的生活带来了许多便捷。其中&#xff0c;LiteAIServer视频智能分析平台的玩手机打电话检测算法技术尤为突出&#xff0c;它利用先进的图像处理和人工智能技术&#xff0c;能够自动识别并监控视频中的玩手机或…

ThingsBoard规则链节点:AWS SNS 节点详解

目录 引言 1. AWS SNS 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 设备报警 3.2 数据同步 3.3 用户通知 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备管理、…

string类的认识

一、初始string类 在 C 中&#xff0c;std::string是标准库提供的用于处理字符串的类。它提供了比 C 风格字符串&#xff08;以\0结尾的字符数组&#xff09;更方便、更安全的字符串处理方式。 要使用std::string&#xff0c;需要包含<string>头文件。并且&#xff0c;st…

Vulnhub靶场 Jangow: 1.0.1 练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 命令执行2. 反弹shell3. 提权4. 补充4.1 其他思路4.2 问题 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/jangow/jangow-01-1.0.1.ova 介绍&#xff1a; Difficulty: easy…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第二十集:制作专门渲染HUD的相机HUD Camera和画布HUD Canvas

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作HUD Camera以及让两个相机同时渲染屏幕二、制作HUD Canvas 1.制作法力条Soul Orb引入库2.制作生命条Health读入数据3.制作吉欧统计数Geo Counter4.制作…