目录
这里用TcpConnection->pipe简单做一个TCP代理。
限速实现原理比较暴力,在收到数据时按数据长度计算出设定速度先应该有的延迟。然后usleep。
安装
composer require workerman/workerman
代码
<?php
use Workerman\Connection\AsyncTcpConnection;
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
require_once __DIR__ . '/vendor/autoload.php';
$web = new Worker("tcp://0.0.0.0:2000");
$web->count = 1;
define('SPEED_LIMIT',1);
function speed_limit($tt,$len = 0){
$speed = SPEED_LIMIT;
$t = (int)round(1000000*($len)/($speed * 1024*1024));
$tt = $t - (microtime(true) - $tt);
if($tt>0){
usleep($tt);
}
};
$web->onConnect = function($connection)
{
$connection_to_80 = new AsyncTcpConnection('tcp://0.0.0.0:1081');
$connection->pipe($connection_to_80);
$connection->onMessage = function ($source, $data) use ($connection_to_80) {
speed_limit(microtime(true),$source->getSendBufferQueueSize() + $source->getRecvBufferQueueSize());
$connection_to_80->send($data);
};
$connection_to_80->pipe($connection);
$connection_to_80->onMessage = function ($source, $data) use ($connection) {
speed_limit(microtime(true),$source->getSendBufferQueueSize() + $source->getRecvBufferQueueSize());
$connection->send($data);
};
$connection_to_80->connect();
};
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
效果
问题
这里的worker数设置的是1,如果设置为2的话,对于多路请求,可以获得双倍的带宽。