workerman TCP服务端

2022-02-02
<?php

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Lib\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('tcp://0.0.0.0:8686');

// true表示守护进程方式运行
Worker::$daemonize = true;

// 进程重启后id不会变,从0开始
echo '进程id:' . $worker->id . PHP_EOL;

// 设置worker的进程数,默认1,建议:IO密集型程序(阻塞式IO,例如:数据库)设置为CPU数量的3-5倍,,CPU密集型程序(没有阻塞式IO,例如:异步IO读取网络资源)设置为CPU数;windows无法设置多进程
$worker->count = 1;

// worker实例的名称,默认none
$worker->name = 'none';

// 当前进程的所有的客户端连接对象数组,键为客户端连接的id
$worker->connections;

// 守护进程运行时,所有输出将重定向到$stdoutFile中,默认/dev/null
Worker::$stdoutFile = '/dev/null';

// workerman自身的日志文件位置
Worker::$logFile = '/tmp/workerman.log';

// pid文件位置,默认在与Workerman目录平行的位置生成,windows不支持
Worker::$pidFile = '/var/run/workerman.pid';

// 实例运行的用户,windows不支持
$worker->user = 'www-data';

// 设置所有连接的默认应用层发送缓冲区大小,默认1M
TcpConnection::$defaultMaxSendBufferSize = 2*1024*1024;

// 设置每个连接接收的最大数据包,包长超过时连接会断开,默认10M
TcpConnection::$defaultMaxPackageSize = 1024000;

// Worker子进程启动时的回调函数,可以实例化数据库连接、文件引入等等
$worker->onWorkerStart = function(Worker $worker)
{
    echo "Worker starting...\n";
};

// 连接时的回调,表示完成了TCP三次握手
$worker->onConnect = function(TcpConnection $connection)
{
	echo '连接的id:' . $connection->id . PHP_EOL;

	// 读取当前连接的worker实例
	$connection->worker;

	// 设置当前连接的发送缓冲区大小(字节),如果客户端接收速度小于服务端发送速度,数据会在发送缓冲区暂存
	$connection->maxSendBufferSize = 102400;

	echo '获取客户端IP:' . $connection->getRemoteIp() . PHP_EOL;

	echo '获取客户端端口:' . $connection->getRemotePort() . PHP_EOL;
};

// 客户端发送数据时的回调
$worker->onMessage = function(TcpConnection $connection, string $data)
{
	echo '接收数据为:' . $data . PHP_EOL;

	// 向客户端发送数据
	// 返回值true表示数据成功写入操作系统层的socket发送缓冲区;null数据以写入连接的应用层发送缓冲区,等待写入系统层的发送缓冲区;false发送失败
	// $data将自动按照指定协议打包后发送,$raw为true时不调用协议打包,默认false
    $connection->send("hello", $raw = false);
};

// 客户端关闭连接时的回调
$worker->onClose = function(TcpConnection $connection)
{
	echo "connection{$connection->id} closed\n";
};

// 连接错误时的回调
$worker->onError = function(TcpConnection $connection, $code, $msg)
{

	// 安全关闭连接,会等待发送缓冲区数据发送完毕后关闭连接,并触发onClose
	// 如果指定$data,将在发送数据$data后关闭连接
	$connection->close($data = null);

	// 立刻关闭连接,无论数据是否发送成功
	$connection->destroy();

    echo "error $code $msg\n";
};

// 运行worker
Worker::runAll();

 

{/if}