workerman + gateway +thinkphp 简单使用

本文介绍Workerman和GatewayWorker的特性与应用,包括环境搭建、客户端与服务端交互过程及ThinkPHP集成案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Workerman是什么?(套用官网)

Workerman是一款纯PHP开发的开源高性能的PHP socket 服务框架。

Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的socket服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。

实际上Workerman类似一个PHP版本的nginx,核心也是多进程+Epoll+非阻塞IO。Workerman每个进程能维持上万并发连接。由于本身常住内存,不依赖Apache、nginx、php-fpm这些容器,拥有超高的性能。同时支持TCP、UDP、UNIXSOCKET,支持长连接,支持Websocket、HTTP、WSS、HTTPS等通讯协以及各种自定义协议。拥有定时器、异步socket客户端、异步Mysql、异步Redis、异步Http、异步消息队列等众多高性能组件。

 2. GatewayWorker是什么?(套用官网)

GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等

GatewayWorker使用经典的Gateway和Worker进程模型。Gateway进程负责维持客户端连接,并转发客户端的数据给BusinessWorker进程处理,BusinessWorker进程负责处理实际的业务逻辑(默认调用Events.php处理业务),并将结果推送给对应的客户端。Gateway服务和BusinessWorker服务可以分开部署在不同的服务器上,实现分布式集群。

 

3. Gatewayworker + thinkphp

数据交互模型:

流程:

  1. 客户端(浏览器)发出socket请求与getwayworker建立连接
  2. 客户端发出http请求(注意是发送http请求处理业务,所有业务都放在tp处理)
  3. tp处理业务逻辑(把client_id与uid绑定、客户端分组、数据库查询等),然后调用gateway的接口把结果数据进行广播
  4. 客户端接收广播的数据,进行视图渲染

 

4. 环境搭建

  1. workerman 与 gateway安装

composer require workerman/workerman
composer require workerman/gateway-worker

  官网实例 点击下载 

  2. 配置

  start_gateway.php文件配置(开启gateway服务,并在注册服务注册)

<?php 

use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;
// 
$context = array(
    'ssl' => array(
        'local_cert'  => '/etc/pki/tls/certs/public.pem', // 或者crt文件
        'local_pk'    => '/etc/pki/tls/private/214498534070135.key',
        'verify_peer' => false
    )
);
// gateway 进程,这里使用websocket协议,这里使用了443端口,所有要加载ssl的配置,websocket://0.0.0.0:443:允许所有任何客户端使用wss协议访问
$gateway = new Gateway("websocket://0.0.0.0:443",$context);

$gateway->transport = 'ssl';
// gateway名称,status方便查看
$gateway->name = 'YourAppGateway';
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '172.31.240.231';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = '172.31.240.231:1238';

// 心跳检测  15秒一次
$gateway->pingInterval = 15;

$gateway->pingNotResponseLimit = 1;
// 当pingData为空,服务器将不会向客户端发送心跳检测(为了节省服务器资源,心跳检测最好由客户端发起)
$gateway->pingData = '';
 if(!defined('GLOBAL_START')) {
   Worker::runAll();
 }

  3. start_businessworker.php(开启businessworker服务,并在注册服务注册)

<?php 
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

// bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = 'YourAppBusinessWorker';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '172.40.239.231:1238';

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
    Worker::runAll();
}

  4. start_register.php(开启注册服务)

<?php 
use \Workerman\Worker;
use \GatewayWorker\Register;

// register 服务必须是text协议
$register = new Register('text://172.40.239.231:1238');

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
    Worker::runAll();
}

   5.  启动服务

    启动

    以debug(调试)方式启动

      php start.php start

    以daemon(守护进程)方式启动

      php start.php start -d

    停止

      php start.php stop

    重启

      php start.php restart

    平滑重启

      php start.php reload

    查看状态

      php start.php status

5. 客户端操作(这是我基于小程序接口,封装的一个socket库)

    var socket = new Socket('wss://wss.xinyuruiyang.com');
    socket.on("open",function (res) {
      console.log('WebSocket连接已打开!')
      _this.setData({
        isOpenSocket: true
      });
    });
  // 初始化链接
  socket.on("init", function (data) {
    _this.setData({
      client_id: data.client_id
    });
    request({
      url: app.requestUrl('Admin/Match/bind'),
      data: {
        client_id: data.client_id,
        room: 1, // 分组1
      },
      success: res => {
        console.log(res, '用户绑定成功!');
      }
    })
  })
 

6. gateway端操作

<?php
use \GatewayWorker\Lib\Gateway;
use \Workerman\Lib\Timer;
class Events
{
    public static $worker_id = null;
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id) {
        // 向当前client_id发送数据(触发客户端的init时间)
        Gateway::sendToClient($client_id, json_encode(["init",["client_id"=>$client_id]]));
    }
}

 

7. tp端操作  

  Gateway::$registerAddress = '172.31.239.230:1238';
   class MatchController extends AdminController {
private function bind_user($room,$client_id,$uid=''){
        if( empty($uid) ){
            $sk = $this->checksession();
            $openid = $this->get_openid($sk);
            $uid = D('User')->where(['openid'=>$openid])->getField('id');
        }

        // client_id与uid绑定
        Gateway::bindUid($client_id, $uid);
        // 加入某个群组(可调用多次加入多个群组)
        Gateway::joinGroup($client_id, $room);
     // 设置session Gateway
::setSession($client_id, ['uid'=>$uid]);
     // 获取客户端分组人数
$number = Gateway::getClientCountByGroup($room); D('Match')->where(['rid'=>$room,'uid'=>$uid,'status'=>['in',['1','2']]])->save(['client_id'=>$client_id]); $message = D('Match')->where(['rid'=>$room,'status'=>['in',['1','2']]])->select(); foreach($message as &$v){ $v['user'] = D('User')->where(['id'=>$v['uid']])->find(); $v['user']['teamside'] = D('Match')->where(['rid'=>$room,'uid'=>$v['uid'],'status'=>['in',['1','2']]])->getField('teamside'); }
     // 向某个房间广播数据 Gateway
::sendToGroup($room, json_encode(["room",$message])); }
 }

 

转载于:https://www.cnblogs.com/dudeyouth/p/9017394.html

<think>好的,我现在需要帮助用户解决如何将WorkermanThinkPHP8集成使用的问题。首先,我要回顾一下用户提供的引用资料,看看之前版本的集成方法,比如ThinkPHP5或3.2是如何做的,然后考虑如何适配到ThinkPHP8。 根据引用[4],在ThinkPHP5中,Workerman是作为扩展集成进来的,可能官方有提供相关的扩展包或文档。但用户现在问的是ThinkPHP8,可能需要检查是否有官方支持的扩展,或者是否有社区维护的版本。例如,引用[1]提到的是think-worker扩展,但原项目地址可能需要确认是否支持TP8。用户提供的引用[3]是关于TP6和Workerman的整合,可能其中的步骤对TP8有参考价值。 首先,我需要确定WorkermanThinkPHP8的兼容性。Workerman本身是一个PHP的socket框架,理论上与任何PHP框架都可以结合,但需要处理框架的初始化、配置和依赖管理。在之前的版本中,可能需要手动启动Worker并初始化框架实例。例如,引用[3]中的TP6案例可能需要创建自定义的Worker类,并在onWorkerStart回调中初始化TP的应用实例,确保每个Worker进程都能正确加载框架的环境。 接下来,步骤可能包括安装Workerman,创建入口文件,初始化ThinkPHP应用,处理请求等。例如,在TP8中,可能需要使用composer安装Workerman,然后创建一个server.php文件作为入口,启动Worker并处理WebSocket或HTTP请求。同时,要确保TP8的路由、控制器等能够被正确调用,可能需要调整自动加载或依赖注入的方式。 另外,引用[2]和[4]提到在TP3.2中的整合方式,可能需要类似的方法,比如在Worker的回调中调用TP的应用类。但是TP8的结构可能与旧版本不同,比如使用了更多的依赖注入和门面模式,所以初始化应用的方式可能需要调整。例如,TP8的应用实例化可能需要通过Container来实现,并且需要确保在Worker进程中正确初始化,避免共享状态导致的问题。 还要注意,Workerman通常以CLI模式运行,而TP8的应用可能需要调整配置以适应命令行环境,比如关闭HTTP相关的中间件,或者处理环境变量的加载。此外,可能需要在Worker启动时加载TP的核心文件,比如vendor/autoload.phpthinkphp/base.php,并调用应用初始化方法。 可能的挑战包括处理TP8的单例模式在多进程环境下的问题,确保每个Worker进程有独立的应用实例,避免内存泄漏或资源竞争。此外,WebSocket和HTTP的集成可能需要不同的处理方式,比如在Worker中定义不同的协议,或者使用GatewayWorker这样的封装库来简化开发。 最后,需要验证这些步骤是否可行,可能需要编写示例代码,并测试是否能成功处理请求。同时,参考现有的社区资源或教程,比如引用[3]中的优快云文章,可能会有更详细的步骤说明,需要检查这些资源是否适用于TP8,或者进行调整。 总结来说,集成WorkermanThinkPHP8的关键步骤可能包括:使用Composer安装Workerman,创建自定义的Worker入口文件,在Worker启动时初始化TP8应用实例,处理请求的路由和响应,以及确保多进程环境下的正确配置和资源管理。</think>### WorkermanThinkPHP8集成使用指南 #### 一、环境准备 1. 安装ThinkPHP8框架 使用composer创建新项目: ```bash composer create-project topthink/think tp8-workerman ``` 2. 安装Workerman依赖 在项目根目录执行: ```bash composer require workerman/workerman ``` #### 二、创建服务入口文件 在项目根目录创建`server.php`: ```php <?php use Workerman\Worker; require __DIR__ . '/vendor/autoload.php'; // 创建HTTP Worker $httpWorker = new Worker("http://0.0.0.0:2345"); $httpWorker->count = 4; // 初始化ThinkPHP应用实例 $httpWorker->onWorkerStart = function(){ require __DIR__ . '/thinkphp/base.php'; (new think\App())->initialize(); }; // 请求处理逻辑 $httpWorker->onMessage = function($connection, $request){ try { ob_start(); think\facade\Route::dispatch($request->get()); $response = ob_get_clean(); $connection->send($response); } catch (\Exception $e) { $connection->send("Error: " . $e->getMessage()); } }; // 运行所有Worker实例 Worker::runAll(); ``` #### 三、配置适配 1. 修改`.env`配置文件: ```ini APP_DEBUG = false APP_TRACE = false ``` 2. 添加路由配置`route/worker.php`: ```php use think\facade\Route; Route::get('worker/test', function(){ return json(['status' => 200, 'message' => 'Workerman集成成功']); }); ``` #### 四、启动与测试 1. 启动服务: ```bash php server.php start ``` 2. 访问测试接口: ```bash curl http://localhost:2345/worker/test # 预期输出: {"status":200,"message":"Workerman集成成功"} ``` #### 五、WebSocket集成示例 ```php $wsWorker = new Worker("websocket://0.0.0.0:2000"); $wsWorker->onMessage = function($connection, $data){ // 调用TP控制器 $result = app('app\controller\Chat')->receive($data); $connection->send($result); }; ``` #### 注意事项 1. 多进程隔离:每个Worker进程独立初始化应用实例[^4] 2. 资源释放:在`onWorkerStop`回调中清理数据库连接 3. 热更新:开发环境使用`php server.php start -d`守护进程模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值