TP6 + GatewayWorker 轻松实现web项目 websocket 功能

这篇具有很好参考价值的文章主要介绍了TP6 + GatewayWorker 轻松实现web项目 websocket 功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、在tp6项目下安装  GatewayWorker 

composer require topthink/think-worker
composer require workerman/gatewayclient

安装成功后在配置文件目录下会出现gateway_worker.php

gatewayworker安装,websocket,php,gateway

开始配置gateway_worker  下边我贴出了我的配置文件供大家参考

return [
    // 扩展自身需要的配置
    'protocol'              => 'websocket', // 协议 支持 tcp udp unix http websocket text
    'host'                  => '127.0.0.1', // 监听地址
    'port'                  => 9099, // 监听端口
    'socket'                => '', // 完整监听地址
    'context'               => [], // socket 上下文选项
    'register_deploy'       => true, // 是否需要部署register
    'businessWorker_deploy' => true, // 是否需要部署businessWorker
    'gateway_deploy'        => true, // 是否需要部署gateway

    // Register配置
    'registerAddress'       => '127.0.0.1:1236',

    // Gateway配置
    'name'                  => 'thinkphp', 
    'count'                 => 1, 
    'lanIp'                 => '127.0.0.1', 
    'startPort'             => 2000,
    'daemonize'             => false,
    'pingInterval'          => 30,
    'pingNotResponseLimit'  => 1,
    'pingData'              => '{"type":"ping"}',

    // BusinsessWorker配置
    'businessWorker'        => [
        'name'         => 'BusinessWorker',
        'count'        => 1,
        'eventHandler' => 'app\common\service\WsEventService',
    ],

];

 下面对gateway 配置部分的属性解释

name : 可以设置Gateway进程的名称,方便status命令中查看统计

count :可以设置Gateway进程的数量,以便充分利用多cpu资源

lanIp :lanIp是Gateway所在服务器的内网IP,如果不做多服务器分布式部署的话默认填写127.0.0.1即可

startPort :官方文档是这样说的  Gateway进程启动后会监听一个本机端口,用来给BusinessWorker提供链接服务,然后Gateway与BusinessWorker之间就通过这个连接通讯。这里设置的是Gateway监听本机端口的起始端口。比如启动了4个Gateway进程,startPort为2000,则每个Gateway进程分别启动的本地端口一般为2000、2001、2002、2003。

官方的话比较绕,其实就可以理解为一下配置了  N个端口  起始端口是 你配置的端口号 至于会启动多少个完全取决你配置的工作进程数 "count"

 registerAddress : 注册服务地址

daemonize : 是否以守护进程模式启动(linux下有效 )

pingInterval :心跳间隔时间

pingNotResponseLimit : 服务端是否允许客户端不发送心跳 如果配置为0则服务端允许客户端不发心跳 ,如果配置为1 客户端必须要在心跳间隔时间(pingInterval)内发送心跳到服务器否则服务器会判定客户端断开而终端连接触发onclose事件。

pingData : 如果pingData 不是空字符串则服务器会在心跳间隔时间(pingInterval)向客户端发送心跳数据

PS:GatewayWorker 通过pingInterval、pingNotResponseLimit、pingData  这三个配置实现了心跳检测机制 ,详情请参见官方文档心跳检测部分 心跳检测-gateway-worker手册

下面对  businessWorker 的配置进行讲解

name :businessWorker启动的进程名

count :businessWorker启动的工作进程数

eventHandler : businessWorker 的事件类(这里要写完整的命名空间)

以下是eventHandler 的示例代码

namespace app\common\service;

use GatewayWorker\Lib\Gateway;

class WsEventService{

    public static function onConnect($client_id)
    {
        Gateway::sendToCurrentClient("Your client_id is $client_id");
    }

    public static function onMessage($client_id , $data){
        Gateway::sendtoCurrentClient("client_id: $client_id -> "."data => $data");
    }

}

当然这里还可以配置更多的事件 详情请参照官方文档的Events类的回调属性-gateway-worker手册

至此我们就可以启动 gateway了

php think worker:gateway

如果你是在windows下会报错  

gatewayworker安装,websocket,php,gateway

这里不支持windows环境并不是说gateway worker不支持windows,而是tp的命令行运行方式不支持windows,原因是(在官方文档中有说明)

 gatewayworker安装,websocket,php,gateway

 官方文档说要分别创建三个php文件分别启动 gateway、register、businessworker服务

我们这里可以通过一个TP自定义命令行搞定 继续上代码!

<?php

declare(strict_types=1);

namespace app\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;

class WebSocket extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('wserver')
            ->addArgument('service', Argument::OPTIONAL, 'workerman service: gateway|register|businessworker', 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)
            ->addOption('daemon', 'd', Option::VALUE_OPTIONAL, 'Run the workerman server in daemon mode.')
            ->setDescription('workerman Server for ThinkPHP');
    }

    protected 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 'businessworker':
                $this->businessWorker($registerAddress, isset($option['businessWorker']) ? $option['businessWorker'] : []);
                break;
            case 'gateway':
                $this->gateway($registerAddress, $host, $port, $option);
                break;
            default:
                $output->writeln("<error>Invalid argument action:{$service}, Expected gateway|register|businessworker .</error>");
                exit(1);
                break;
        }

        Worker::runAll();
    }

    /**
     * 启动register
     * @access public
     * @param  string   $registerAddress
     * @return void
     */
    public function register($registerAddress)
    {
        // 初始化register
        new Register('text://' . $registerAddress);
    }

    /**
     * 启动businessWorker
     * @access public
     * @param  string   $registerAddress registerAddress
     * @param  array    $option 参数
     * @return void
     */
    public function businessWorker($registerAddress, $option = [])
    {
        // 初始化 bussinessWorker 进程
        $worker = new BusinessWorker();

        $this->option($worker, $option);

        $worker->registerAddress = $registerAddress;
    }

    /**
     * 启动gateway
     * @access public
     * @param  string   $registerAddress registerAddress
     * @param  string   $host 服务地址
     * @param  integer  $port 监听端口
     * @param  array    $option 参数
     * @return void
     */
    public function gateway($registerAddress, $host, $port, $option = [])
    {
        // 初始化 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, isset($option['context']) ? $option['context'] : []);

        // 以下设置参数都可以在配置文件中重新定义覆盖
        $gateway->name                 =  'Gateway';
        $gateway->count                = 4;
        $gateway->lanIp                = '127.0.0.1';
        $gateway->startPort            = 2000;
        $gateway->pingInterval         = 10;
        $gateway->pingNotResponseLimit = 1;
        $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, array $option = [])
    {
        // 设置参数
        if (!empty($option)) {
            foreach ($option as $key => $val) {
                $worker->$key = $val;
            }
        }
    }
}

下边我们就可以通过运行这个tp自定义命令来分别启动三个服务

php think wserver register   //启动 register服务
php think wserver businessworker //启动 businessworker服务
php think wserver gateway //启动 gateway服务

这样我们需要在windows上打开三个cmd窗体分别执行这三条命令 如果嫌麻烦的话可以编辑个bat脚本一次启动这三个服务, 将下边代码保存成 xxx.bat 就可以了

start php think wserver register
start php think wserver businessworker
start php think wserver gateway

最后执行这个bat脚本就可以了(通过命令行执行或者双击执行都可以)

gatewayworker安装,websocket,php,gateway

 到这里我们就可以在tp6项目中任何一个地方通过调用 GatewayWorker\Lib\Gateway 类的方法向客户端推送消息了 详情请参见官方文档  Lib/Gateway类提供的接口-gateway-worker手册

Gateway::sendToClient($client_id,$message);

windows 启动服务部分参照了  八戒王的博客《GatewayWorker Not Support On Windows.》 特此鸣谢!GatewayWorker Not Support On Windows._windows不支持 geteway_八戒王的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-722700.html

到了这里,关于TP6 + GatewayWorker 轻松实现web项目 websocket 功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • tp6安装并使用rabbitMQ

    最近因为业务需要,要用到MQ就去研究了一下,说实话,安装环境给我搞自闭了,大概是我太菜 刚开始使用yum换源,各种安装卸载始终找不到自己要用的版本,后来全部卸载,下载安装包 编译安装解百忧 我用的是erlang 25.3 的版本,MQ使用的是3.11.3的版本,符合官方要求,这里的版本是有强

    2024年02月08日
    浏览(64)
  • tp6 v3微信退款

    调用

    2024年02月13日
    浏览(62)
  • tp6用redis存储session

    随着业务量的增加,很多时候会需要共享session的情况。共享session,其实就是说多台服务器共用一个session,或者是说一个主域跟多个子域之间共用一个session。工作中用tp也多一些,那么,我就用tp6来给大家讲解一下。 在共享session,我们需要用到redis。这儿我假设大家都能读懂

    2024年02月08日
    浏览(65)
  • TP6 对接阿里云短信接口2.0

    首先下载 安装阿里云短信SDK composer require alibabacloud/sdk 安装 Alibaba Cloud SDK for PHP 作为依赖项 composer require alibabacloud/darabonba-openapi 最后安装对应的包 composer require alibabacloud/dysmsapi-20170525  上面3个都下载了,官方网站并没有说明下载 sdk,这个没有下载,查询资料花了几个小时,

    2024年02月16日
    浏览(69)
  • TP6----------阿里云短信包验证码登录

    首先开通阿里云短信包,之后申请短信包签名,这里大家自行去阿里云申请 安装阿里云sdk 首先创建Sample类方便调用,我们需要有短信签名,签名模板,阿里云keyId和accessKeySecret 阿里云key在阿里云首页,右上角有个acesskey管理就可以看到 Sample.php文件 业务逻辑层生成随机验证码

    2024年02月15日
    浏览(64)
  • tp6 rules内置验证规则thinkphp

    1、验证某个字段必须:‘name’=‘require’ 2、验证某个字段的值是否为纯数字:‘num’=‘number’ 3、验证某个字段的值是否为整数:‘num’=‘integer’ 4、验证某个字段的值是否为浮点数字:‘num’=‘float’ 5、验证某个字段的值是否为布尔值:‘num’=‘boolean’ 6、验证某个字

    2024年04月28日
    浏览(51)
  • tp6怎么做阿里云OSS存储呢?

    作者:陈业贵 华为云享专家 51cto(专家博主 明日之星 TOP红人) 阿里云专家博主 阿里云oss存储是得买的。买后,还要获取参数。填入代码中就可以啦 获得四个参数: $accessKeyId $accessKeySecret $endpoint $bucket 不然不对了哈 告诉你怎么做阿里云OSS存储.

    2024年02月15日
    浏览(59)
  • TP6 使用闭合语句查询多个or的模型语句

    需要传入参数查询的,可以参照下面的:         查询出学校名称和昵称中有中学的所有学校

    2024年02月11日
    浏览(50)
  • web网页端使用webSocket实现语音通话功能(SpringBoot+VUE)

    最近在写一个web项目,需要实现web客户端之间的语音通话,期望能够借助webSocket全双工通信的方式来实现,但是网上没有发现可以正确使用的代码。网上能找到的一个代码使用之后 只能听到“嘀嘀嘀”的杂音 解决方案: 使用Json来传递数据代替原有的二进制输入输出流 技术

    2024年02月02日
    浏览(116)
  • tp6的runtime/Logs目录下产生大量日记文件,怎么取消自动生成?

    一开始查了好多网上提供的,很幸运都是抄袭别人的,没一个成功,最后无奈只能自己解决方法 其实很简单,不用修改config/log.php文件,没用因为只要有登入错误,警告,消息或者sql错误都会写入 解决方法: 关闭调试模式 配置数据库文件  .env文件 true改为false即可  总结:

    2024年02月16日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包