TP5.0.24+Workerman 进行 socket 通讯

1.安装 Workerman
安装GatewayWorker内核文件(不包含start_gateway.php start_businessworker.php等启动入口文件),直接上composer

composer require workerman/gateway-worker

2.创建 Workerman 启动文件
创建一个自定义命令类文件来启动 Socket 服务端,新建

application/push/command/Workerman.php
namespace app\push\command;

use Workerman\Worker;
use GatewayWorker\Register;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class Workerman extends Command
{

    protected function configure()
    {
        $this->setName('workerman')
            ->addArgument('action', Argument::OPTIONAL, "action  start|stop|restart")
            ->addArgument('type', Argument::OPTIONAL, "d -d")
            ->setDescription('workerman chat');
    }

    protected function execute(Input $input, Output $output)
    {
        global $argv;
        $action = trim($input->getArgument('action'));
        $type   = trim($input->getArgument('type')) ? '-d' : '';

        $argv[0] = 'chat';
        $argv[1] = $action;
        $argv[2] = $type ? '-d' : '';

        $this->start();
    }

    private function start()
    {
        $this->startGateWay();
        $this->startBusinessWorker();
        $this->startRegister();
        Worker::runAll();
    }

    private function startBusinessWorker()
    {
        // bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'YourAppBusinessWorker';
        // bussinessWorker进程数量
        $worker->count = 4;
        //设置处理业务的类,此处制定Events的命名空间
        $worker->eventHandler= \app\push\controller\Events::class;
        // 服务注册地址
        $worker->registerAddress = '127.0.0.1:1238';
    }

    private function startGateWay()
    {
        // gateway 进程,这里使用Text协议,可以用telnet测试
        $gateway = new Gateway("websocket://0.0.0.0:8282");
        // gateway名称,status方便查看
        $gateway->name = 'YourAppGateway';
        // gateway进程数
        $gateway->count = 4;
        // 本机ip,分布式部署时使用内网ip
        $gateway->lanIp = '127.0.0.1';
        // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
        // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
        $gateway->startPort = 20003;
        // 服务注册地址
        $gateway->registerAddress = '127.0.0.1:1238';
        // 心跳间隔
        $gateway->pingInterval = 55;
        $gateway->pingNotResponseLimit = 1;
        // 心跳数据
        $gateway->pingData = '{"type":"ping"}';
    }

    private function startRegister()
    {
        new Register('text://0.0.0.0:1238');
    }
}

配置 application/command.php 文件

return [
    'app\common\command\Workerman',
];

3.创建事件监听文件
创建 application/push/controller/Events.php 文件来监听处理 workerman 的各种事件。

namespace app\push\controller;

use GatewayWorker\Lib\Gateway;

class Events
{
    /**
     * 当客户端发来消息时触发
     * @param int $client_id 连接id
     * @param mixed $message 具体消息
     */
    public static function onMessage($client_id, $message)
    {
        $message_data = json_decode($message,true);
        if (!$message_data) {
            return ;
        }
        switch($message_data['type']) {
            case 'pong':
                return;
            case 'handshake':
                $new_message    = [
                    'type'      => $message_data['type'],
                    'client_id' => $client_id,
                    'time'      => date('H:i:s')
                ];
                Gateway::sendToClient($client_id, json_encode($new_message));
                return;
            case 'send':
                if (!isset($message_data['toClientUid'])) {
                    throw new \Exception("toClient not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
                }
                $toUid          = $message_data['toClientUid'];
                $message        = $message_data['content'];
                $new_message    = [
                    'type'      => 'reception',
                    'content'   => $message,
                    'time'      => date('H:i:s'),
                    'timestamp' => time(),
                    'c_type'    => $message_data['c_type'],
                    'primary'   => $message_data['Db_id']
                ];
                //发送者角色
                $source_info = explode('_', $message_data['source']);
                if ($source_info[0] == 'U') {
                    //为了安全,特意做了加密
                    $new_message['source'] = encrypt_hopeband($source_info[1], 'E', 'XXXXXXX');
                }

                return Gateway::sendToUid($toUid, json_encode($new_message));
        }
    }

    /**
     * 当用户连接时触发的方法
     * @param integer $client_id 连接的客户端
     * @return void
     */
    public static function onConnect($client_id)
    {
        Gateway::sendToClient($client_id, json_encode(array(
            'type'      => 'init',
            'client_id' => $client_id
        )));
    }

    /**
     * 当用户断开连接时触发的方法
     * @param integer $client_id 断开连接的客户端
     * @return void
     */
    public static function onClose($client_id)
    {
        Gateway::sendToAll("client[$client_id] logout\n");
    }

    /**
     * 当进程启动时
     * @param integer $businessWorker 进程实例
     */
    public static function onWorkerStart($businessWorker)
    {
        echo "WorkerStart\n";
    }

    /**
     * 当进程关闭时
     * @param integer $businessWorker 进程实例
     */
    public static function onWorkerStop($businessWorker)
    {
        echo "WorkerStop\n";
    }
}

4.启动 Workerman 服务端
以debug(调试)方式启动

以debug(调试)方式启动
php think workerman start
//以daemon(守护进程)方式启动
php think workerman start d
//停止
php think workerman stop
//重启
php think workerman restart
//平滑重启
php think workerman reload
//查看状态
php think workerman status

//当你看到如下结果的时候,workerman已经启动成功了。
Workerman[chat] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.5.11          PHP version:7.0.29
------------------------ WORKERS -------------------------------
user          worker          listen                    processes status
tegic         Gateway         websocket://0.0.0.0:8282   1         [OK]
tegic         BusinessWorker  none                       1         [OK]
tegic         Register        text://0.0.0.0:1236        1         [OK]
----------------------------------------------------------------
Press Ctrl+C to stop. Start success.

windows 版本无法启动,已经在商城项目中使用

猜你喜欢

转载自blog.51cto.com/13955671/2423686