Open AlwaysCompile opened 8 months ago
<?php
class ProxyServer
{
protected $frontends;
protected $backends;
/**
* @var swoole_server
*/
protected $serv;
protected $index = 0;
protected $mode = SWOOLE_BASE;
protected $backendServer = array('host' => '127.0.0.1', 'port' => '80');
function run()
{
$serv = new Swoole\Server("127.0.0.1", 9509, $this->mode);
$serv->set(array(
'worker_num' => 8, //worker process num
//'backlog' => 128, //listen backlog
//'open_tcp_keepalive' => 1,
//'log_file' => '/tmp/swoole.log', //swoole error log
));
$serv->on('WorkerStart', array($this, 'onStart'));
$serv->on('Receive', array($this, 'onReceive'));
$serv->on('Close', array($this, 'onClose'));
$serv->on('WorkerStop', array($this, 'onShutdown'));
$serv->start();
}
function onStart($serv)
{
$this->serv = $serv;
echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n";
}
function onShutdown($serv)
{
echo "Server: onShutdown\n";
}
function onClose($serv, $fd, $from_id)
{
if (isset($this->frontends[$fd]))
{
$backend_socket = $this->frontends[$fd];
$backend_socket->closing = true;
$backend_socket->close();
unset($this->backends[$backend_socket->sock]);
unset($this->frontends[$fd]);
}
echo "onClose: frontend[$fd]\n";
}
function onReceive($serv, $fd, $from_id, $data)
{
if (!isset($this->frontends[$fd]))
{
$socket = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
$socket->closing = false;
$socket->on('connect', function (swoole_client $socket) use ($data)
{
$socket->send($data);
});
$socket->on('error', function (swoole_client $socket) use ($fd)
{
echo "ERROR: connect to backend server failed\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
});
$socket->on('close', function (swoole_client $socket) use ($fd)
{
echo "onClose: backend[{$socket->sock}]\n";
unset($this->backends[$socket->sock]);
unset($this->frontends[$fd]);
if (!$socket->closing)
{
$this->serv->close($fd);
}
});
$socket->on('receive', function (swoole_client $socket, $_data) use ($fd)
{
$this->serv->send($fd, $_data);
});
if ($socket->connect($this->backendServer['host'], $this->backendServer['port']))
{
$this->backends[$socket->sock] = $fd;
$this->frontends[$fd] = $socket;
}
else
{
echo "ERROR: cannot connect to backend server.\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
}
}
else
{
/**
* @var $socket swoole_client
*/
$socket = $this->frontends[$fd];
$socket->send($data);
}
}
}
$serv = new ProxyServer();
$serv->run();
Hello @NathanFreeman that is still using the same broken script. Swoole no longer supports clients with SWOOLE_SOCK_ASYNC. You can see this here: https://github.com/swoole/ext-async
Does swoole no longer support this functionality in the latest versions or is there a way to perform the proxy using supported methods? It looks like swoole has removed async client support and only supports coroutines. Can routines be used to make the proxy script work as intended?
Please answer these questions before submitting your issue.
The example script is broken: https://github.com/swoole/proxy-server/blob/master/tcp-proxy.php
The working script
It is broken because swoole no longer supports callbacks for clients? The "on()" method cannot be found. Swoole also does not seem to provide a way to pipe data and events between sockets, so there is not a way to get data and relay it back to the client as a proxy server should do.
How can the example script be made working again with the new coroutine system?