Re: php websocket server and clients

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks Marcos for your answer.

The problem is really just in the few lines I posted before. If you run those lines do you get my same problem?

Anyway, for completeness, I'm posting the complete code. If you run it, you will notice that before starting the React loop it takes quite a long time, and this time is taken by the stream_socket_client operation. I would like to know why it takes such a long time, but only if I have more than 35 elements in my loop.

The main file is

<?php

use Ratchet\Server\IoServer;
use MyRatchet\WebSocketClient;
use MyRatchet\RatchetServer;
use MyRatchet\RatchetClient;

require __DIR__ . '/vendor/autoload.php';

$s_fileTarget = __DIR__ . "/../files/";
if (!is_dir($s_fileTarget)) {
    mkdir($s_fileTarget);
}

$i_count = 0;
$f_start = microtime(true);

$s_content = file_get_contents('http://rss.cnn.com/rss/cnn_topstories.rss');
$I_feed = new SimpleXmlElement($s_content);

$server = IoServer::factory(
    new RatchetServer(),
    8080
);

foreach ($I_feed->channel->item as $I_entry) {
    $client = new RatchetClient($I_entry);
    $wsClient = new WebSocketClient($client, $server->loop);
}

$server->run();

The class RatchetServer in in the file MyRatchet\RatchetServer.php

<?php

namespace MyRatchet;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class RatchetServer implements MessageComponentInterface
{
    protected $clients;

    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn)
    {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";

        $conn->send(json_encode(['connected']));
    }

    public function onMessage(ConnectionInterface $from, $msg)
    {
echo sprintf('Connection %d sending message "%s"' . "\n", $from->resourceId, $msg);
    }

    public function onClose(ConnectionInterface $conn)
    {
// The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}

The class WebsocketClient is in the same directory as the previous one and is as follows:

<?php

namespace MyRatchet;

use React\EventLoop\StreamSelectLoop;
use React\Socket\Connection;
use WebSocketClient\Exception\ConnectionException;

class WebSocketClient
{
    /**
     * @var WebSocketClientInterface
     */
    private $client;

    /**
     * @var StreamSelectLoop
     */
    private $loop;

    /**
     * @var string
     */
    private $host;

    /**
     * @var int
     */
    private $port;

    /**
     * @var string
     */
    private $path;

    /**
     * @var string
     */
    private $origin;

    /**
     * @var Connection
     */
    private $socket;

    /**
     * @param WebSocketClientInterface $client
     * @param StreamSelectLoop $loop
     * @param string $host
     * @param int $port
     * @param string $path
     * @param null|string $origin
     */
    public function __construct(
        WebSocketClientInterface $client,
        StreamSelectLoop $loop,
        $host = '127.0.0.1',
        $port = 8080,
        $path = '/',
        $origin = null
    ) {
        $this->setClient($client);
        $this->setLoop($loop);
        $this->setHost($host);
        $this->setPort($port);
        $this->setPath($path);
        $this->setOrigin($origin);

        $this->connect();
        $client->setClient($this);
    }

    /**
     * Connect client to server
     *
     * @throws ConnectionException
     * @return $this
     */
    public function connect()
    {
        $root = $this;

$client = stream_socket_client("tcp://{$this->getHost()}:{$this->getPort()}");
        if (!$client) {
            throw new \Exception('Unable to connect to server');
        }
        $this->setSocket(new Connection($client, $this->getLoop()));
        $this->getSocket()->on('data', function ($data) use ($root) {
            $root->parseData($data);
        });

        return $this;
    }

    /**
     * Parse received data
     *
     * @param $response
     */
    private function parseData($response)
    {
        $content = json_decode($response, true);
        $this->receiveData($content);
    }

    /**
     * @param $data
     */
    private function receiveData($data)
    {
        $this->getClient()->onEvent($data);
    }

    /**
     * @param WebSocketClientInterface $client
     * @return $this
     */
    public function setClient(WebSocketClientInterface $client)
    {
        $this->client = $client;
        return $this;
    }

    /**
     * @return WebSocketClientInterface
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * @param StreamSelectLoop $loop
     * @return $this
     */
    public function setLoop(StreamSelectLoop $loop)
    {
        $this->loop = $loop;
        return $this;
    }

    /**
     * @return StreamSelectLoop
     */
    public function getLoop()
    {
        return $this->loop;
    }

    /**
     * @param string $host
     * @return $this
     */
    public function setHost($host)
    {
        $this->host = (string)$host;
        return $this;
    }

    /**
     * @return string
     */
    public function getHost()
    {
        return $this->host;
    }

    /**
     * @param int $port
     * @return $this
     */
    public function setPort($port)
    {
        $this->port = (int)$port;
        return $this;
    }

    /**
     * @return int
     */
    public function getPort()
    {
        return $this->port;
    }

    /**
     * @param string $path
     * @return $this
     */
    public function setPath($path)
    {
        $this->path = $path;
        return $this;
    }

    /**
     * @return string
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     * @param null|string $origin
     */
    public function setOrigin($origin)
    {
        if (null !== $origin) {
            $this->origin = (string)$origin;
        } else {
            $this->origin = null;
        }
    }

    /**
     * @return null|string
     */
    public function getOrigin()
    {
        return $this->origin;
    }

    /**
     * @param Connection $socket
     * @return $this
     */
    public function setSocket(Connection $socket)
    {
        $this->socket = $socket;
        return $this;
    }

    /**
     * @return Connection
     */
    public function getSocket()
    {
        return $this->socket;
    }
}

And the class RatchetClient is the following:

<?php

namespace MyRatchet;

class RatchetClient implements WebSocketClientInterface
{
    /**
     * @var MyRatchet\WebSocketClient
     */
    private $client;

    /**
     * @var SimpleXMLElement
     */
    private $entry;

    public function __construct(\SimpleXMLElement $entry)
    {
        $this->entry = $entry;
    }

    public function onEvent($message)
    {
        if ($message == ['connected']) {
            $as_namespaces = $this->entry->getNameSpaces(true);
            if (array_key_exists('media', $as_namespaces)) {
                $I_media = $this->entry->children($as_namespaces['media']);
foreach ($I_media->content->attributes() as $s_key => $s_value) {
                    if ('url' == $s_key) {
                        $s_imgUrl = $s_value;
//file_put_contents($s_fileTarget . ++$i_count . '.jpg', fopen($s_imgUrl, 'r'));
                    }
                }
            }
//$this->client->getSocket()->write("Processing: " . $this->entry->title .' -> '. $this->entry->link);
            var_dump($this->entry->title);
        }
    }

    public function setClient(WebSocketClient $client)
    {
        $this->client = $client;
    }
}

On 19/05/2015 09:56, Marcos Almeida Azevedo wrote:
On Wed, May 13, 2015 at 10:25 PM, Marco Perone <m.perone@xxxxxxxxx> wrote:

Hi all,

I'm trying to build a script that creates a websocket server and some
clients that connects to it.

A huge synthesis of the code could be:

|$server=  stream_socket_server("tcp://127.0.0.1:8080");

for  ($i=  1;  $i<=  50;  $i++)  {
     var_dump($i);
     stream_socket_client("tcp://127.0.0.1:8080");
}|



Would you kindly share more code?


everything is fine for the first 35 clients, then the connections start to
slow down and they happen almost one per second.

What is the reason for these delays? Is it a configuration setting?
Something due to my operative system?

I'm using PHP 5.6.4-4 on ubuntu 15.04

Thanks!





--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php





[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux