0

I managed to create a web service that listens on port 80 for http requests and handles ajax calls and also long polling.

But I'm stuck at creating a similar websocke server in the same php file

<?php
require_once('vendor/autoload.php');

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat 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);
        $conn->send('aa');
        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($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();
    }
}


$loop = React\EventLoop\Factory::create();

$swsa=new Chat;
$webSock = new React\Socket\Server($loop);
$webSock->listen(8687, '127.0.0.1'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            $swsa
        )
    ),
    $webSock
);

$app = function ($request, $response) {
    //some code here to manage requests
    $response->writeHead(200,array('Content-Type'=>'application/json'));
    $response->end(json_encode(array('ok'=>'ok')));
};
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket, $loop);
$http->on('request', $app);
$socket->listen(8485);

$loop->run();

Code in browser:

var wsUri = "ws://127.0.0.1:8687/";
websocket = new WebSocket(wsUri);

This triggers an error in the browser

Firefox can't establish a connection to the server at ws://127.0.0.1:8687/
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
vlad b.
  • 695
  • 5
  • 14

1 Answers1

1

Your IoServer initialization is incorrect. If you check the code for IoServer class, you will find:

public function __construct(MessageComponentInterface $app,ServerInterface $socket, LoopInterface $loop = null)

and

public function run() {
    if (null === $this->loop) {
        throw new \RuntimeException("A React Loop was not provided during instantiation");
    }

    // @codeCoverageIgnoreStart
    $this->loop->run();
    // @codeCoverageIgnoreEnd
}

The IoServer class object has no loop assigned to it and hence it fails to execute. Try passing loop as your third argument.

Arun Poudel
  • 627
  • 6
  • 21