tp5+php7.1+Workerman(GatewayWorker) 实现pc端信息传给app

公司需要实现一个功能:pc端点击按钮,调用接口,并且将pc端请求的数据发送给app端,使app获取数据后执行后续功能。
环境:宝塔环境+tp5.0+php7.1
一开始用了Workerman搞了2天后发现开发难度较大,而且不稳定。后来发现了GatewayWorker,使用简单,内置很多类可以直接调用,非常友好。GatewayWorker是基于Workerman实现的一个更完善的专门用于实现TCP长连接的项目框架。

一、宝塔禁用函数

禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork。

二、tp5安装GatewayWorker,进入根目录(不是public目录)

1.安装GatewayWorker

 composer require workerman/gateway-worker: "3.0.22"

2.安装workman

composer require topthink/think-worker: "1.0.0"

3.安装gatewayclient

composer require  workerman/gatewayclient: "^3.1"

三、在项目根目录新建 start.php

ThinkPHP 5.1 使用该文件

<?php
/**
 * workerman + GatewayWorker
 * 此文件只能在Linux运行
 * run with command
 * php start.php start
 */
// [ 应用入口文件 ]
namespace think;

ini_set('display_errors', 'on');
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("start.php not support windows.\n");
}
// 检查扩展
if(!extension_loaded('pcntl'))
{
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
if(!extension_loaded('posix'))
{
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}

define('APP_PATH', __DIR__ . '/../application/');

// 标记是全局启动
define('GLOBAL_START', 1);

// 加载基础文件
require __DIR__ . '/thinkphp/base.php';
// 执行应用并响应
Container::get('app')->bind('chat/Gate')->run()->send();

ThinkPHP 5.0 使用该文件

<?php
/**
 * workerman + GatewayWorker
 * 此文件只能在Linux运行
 * run with command
 * php start.php start
 */
ini_set('display_errors', 'on');
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("start.php not support windows.\n");
}
//检查扩展
if(!extension_loaded('pcntl'))
{
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
if(!extension_loaded('posix'))
{
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','chat/Gate');
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';

四、创建控制器 chat/Gate

<?php
/**
 * 需要在Linux系统控制台进行启动,启动文件位于根目录的start.php文件中
 * Windows无法进行同时启动多个协议
 * 由于PHP-CLI在windows系统无法实现多进程以及守护进程,所以windows版本Workerman建议仅作开发调试使用。
 */
namespace app\chat\controller;
use Workerman\Worker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use GatewayWorker\BusinessWorker;

class Gate
{
    /**
     * 构造函数
     * @access public
     */
    public function __construct(){
       
        //初始化各个GatewayWorker
        //初始化register register 服务必须是text协议
        $register = new Register('text://0.0.0.0:1236');
        //初始化 bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'ChatBusinessWorker22';
        // bussinessWorker进程数量
        $worker->count = 4;
        // 服务注册地址
        $worker->registerAddress = '127.0.0.1:1236';
        //设置处理业务的类,此处制定Events的命名空间
        $worker->eventHandler = 'app\chat\controller\Events';
        
        
        $gateway = new Gateway("websocket://0.0.0.0:9502");
        $gateway->name = 'RoomGateway';
        $gateway->count = 4;
        $gateway->lanIp = '127.0.0.1';
        $gateway->startPort = 2900;
        $gateway->registerAddress = '127.0.0.1:1236';
        
        //运行所有Worker;
        Worker::runAll();
    }
}

五、创建控制器 chat/Events

<?php
namespace app\chat\controller;
use think\Controller;
use think\Db;
use think\Session;
/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
//declare(ticks=1);
/**
 * 聊天主逻辑
 * 主要是处理 onMessage onClose
 */
use \GatewayWorker\Lib\Gateway;

class Events
// class Events extends Controller
{
    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    public static function onWebSocketConnect($client_id, $data)
    {
       if (isset($data['get']['user_id']) && $data['get']['user_id']){
           $user_id = $data['get']['user_id'];
           Gateway::bindUid($client_id, $user_id);  
           Gateway::sendToClient($client_id, '你连接了我 ID:'.$user_id);
       }
    }
      /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        // 向所有人发送
        //Gateway::sendToAll("$client_id login\r\n");
    }
    

    public static function onWorkerStart($businessWorker)
    {


    }
    /**
     * 有消息时
     * @param int $client_id
     * @param mixed $message
     */
    public static function onMessage($client_id, $message)
    {
      
    }

    /**
     * 当客户端断开连接时
     * @param integer $client_id 客户端id
     */
    public static function onClose($client_id)
    {
     
    }
}

六、pc端调用接口

<?php
namespace app\index\controller;
use \GatewayWorker\Lib\Gateway;
class Index
{
    public function index()
    {
       try {
         	   	$user_id = input('post.user_id');
        	   	$mobile = input('post.mobile');
               	$data = array('user_id' => $user_id, 'mobile' => $mobile);
               	// 检查用户是否连接
                if(Gateway::isUidOnline($user_id)){
                    Gateway::sendToUid($user_id, json_encode($data));
                }else{
                   return resultArray(['error' => '连接失败']);   
                }
                 return resultArray(['data' => '连接成功']);
            } catch (\Exception $e) {
                return resultArray(['error' => '连接失败']); 
            }
    }
}

七、启动websocket程序

1、防火墙打开95021236端口,执行下面命令
//运行 测试运行
php start.php start
 
//linux运行 长链接
php start.php start -d
//停止 
php start.php stop
//检测端口是否以被占用
netstat -an | grep 80
 
//关闭某个进程
sudo kill -9 进程ID
 
如果修改文件后一定要先停止在运行一下文件,否则不生效

我这里默认php版本是7.3,所以启动时需要指定php版本
查看宝塔默认php版本。网站-》高级设置-》PHP命令版本
请添加图片描述
指定版本执行命令

#进入项目根目录,不是public目录
cd /www/wwwroot/crm1002`
#指定php版本开起
/www/server/php/71/bin/php start.php start -d`

请添加图片描述

八、宝塔里配置wss。 使用wss访问,能够更加稳定

必须先配置ssl
1、配置文件添加内容:
在这里插入图片描述

代码如下:

map $http_upgrade $connection_upgrade {  
default upgrade;  ''      close;
}
# 这里的backend可以改成自己需要的名称,我自己用的是wss。
upstream wss {  
# 这里的localhost是域名,也可以是外网ip,9502是我ws开启的端口。  
server localhost:9502;
}

2.设置伪静态
请添加图片描述
代码如下:

location /wss {
            proxy_pass http://127.0.0.1:9502;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            rewrite /wss/(.*) /$1 break;
            proxy_redirect off;
  }

九、使用apipost或者postman模拟请求
在这里插入图片描述

访问路由为

wss://域名/wss?user_id=126

参考文档:
宝塔Nginx配置wss:https://www.kancloud.cn/bishengzhu/twword/2056626
ThinkPHP 5 gatewayworker文档:https://www.kancloud.cn/phpcp/thinkphp5/2287102
gateway-worker使用文档:https://www.workerman.net/doc/gateway-worker/bind-uid.html

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值