Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example script in swoole github is broken. How can the proxy server script be updated? #5178

Open
AlwaysCompile opened this issue Nov 4, 2023 · 2 comments

Comments

@AlwaysCompile
Copy link

Please answer these questions before submitting your issue.

  1. What did you do? If possible, provide a simple script for reproducing the error.

The example script is broken: https://github.com/swoole/proxy-server/blob/master/tcp-proxy.php

  1. What did you expect to see?

The working script

  1. What did you see instead?

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?

@NathanFreeman
Copy link
Member

<?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();

@AlwaysCompile
Copy link
Author

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants