Tegic Blog

在 ThinkPHP5.1 使用 Workerman 进行 socket 通讯

最近在做一个聊天系统,权衡了 swoole 和 workerman ,刚好在 laravel 社区看到了 laravel 框架的 workerman socket 通讯文章,最后选择了 workerman,现在移植到 thinkphp5.1 框架上来。

1.安装 Workerman

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

$ composer require workerman/gateway-worker

2.创建 Workerman 启动文件

创建一个自定义命令类文件来启动 Socket 服务端,新建 application/common/command/Workerman.php

<?php
/**
 * User: Tegic
 * Date: 2018/6/13
 * Time: 09:36
 */

namespace app\common\command;

use app\workerman\Events;
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 Workerman\Worker;

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()
	{
		$worker                  = new BusinessWorker();
		$worker->name            = 'BusinessWorker';
		$worker->count           = 1;
		$worker->registerAddress = '127.0.0.1:1236';
		$worker->eventHandler    = Events::class;
	}
	
	private function startGateWay()
	{
		$gateway = new Gateway("websocket://0.0.0.0:8282");
		$gateway->name                 = 'Gateway';
		$gateway->count                = 1;
		$gateway->lanIp                = '127.0.0.1';
		$gateway->startPort            = 2300;
		$gateway->pingInterval         = 30;
		$gateway->pingNotResponseLimit = 0;
		$gateway->pingData             = '{"type":"@heart@"}';
		$gateway->registerAddress      = '127.0.0.1:1236';
	}
	
	private function startRegister()
	{
		new Register('text://0.0.0.0:1236');
	}
}

配置 application/command.php 文件

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

3.创建事件监听文件

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

<?php
/**
 * User: Tegic
 * Date: 2018/6/13
 * Time: 09:47
 */

namespace app\workerman;

use GatewayWorker\Lib\Gateway;

class Events
{
	
     public static function onWorkerStart($businessWorker)
    {
    }

    public static function onConnect($client_id)
    {
    }

    public static function onWebSocketConnect($client_id, $data)
    {
    }

    public static function onMessage($client_id, $message)
    {
    }

    public static function onClose($client_id)
    {
    }
}

4.启动 Workerman 服务端

以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.