建立公司网站,商场大型话题活动策划网站,绵竹网站建设,重庆做网站 帮助中心应用场景说明#xff1a;通过建立通信#xff0c;不同用户进行消息推送或数据更新#xff0c;因为本身需要作为服务端进行主动消息推送#xff0c;因此使用Gateway方式#xff0c;如果不需要的可以不采用这种形式#xff0c;以下内容仅为参考#xff0c;具体业务场景通过建立通信不同用户进行消息推送或数据更新因为本身需要作为服务端进行主动消息推送因此使用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 langen
headmeta charsetUTF-8titleTitle/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 三、使用Gateway
如果直接使用 php think worker:gateway 就会提示GatewayWorker Not Support On Windows.具体原因简单说明php think worker:gateway就是在同一个php文件里启动了多个worker因为不能成功运行所以tp的命令行提前做了判定显示不支持在windows下运行大家自行搜一下具体原因即可。
具体解决思路自定义命令进行运行根据以下步骤进行参考
1.创建命令
php think make:command commonWorkerMain
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(errorInvalid 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 langen
headmeta charsetUTF-8titleTitle/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
完成以上工作就可以顺利进行啦。