-
-
Save cboden/3119135 to your computer and use it in GitHub Desktop.
<?php | |
$collection = new RouteCollection; | |
$collection->add('chatRoom', new Route('/demo', array( | |
'_controller' => new ChatRoom | |
, 'allowedOrigins' => 'socketo.me' | |
))); | |
$collection->add('echo', new Route('/echo', array( | |
'_controller' => new AbFuzzyServer | |
, 'allowedOrigins' => '*' | |
))); | |
$collection->add('uhOh', new Route('/what/{happens}/{now}', array( | |
'_controller' => new Trouble | |
))); | |
$router = new WsRouter; | |
$router->addCollection($collection); | |
$wsserv = new WebSocket($router); | |
$server = new IoServer($wsserv); | |
$server->run(); |
<?php | |
use Ratchet\ConnectionInterface; | |
use Ratchet\MessageComponentInterface; | |
class Trouble implements MessageComponentInterface { | |
public function onOpen(ConnectionInterface $conn, , $happens = '', $now = '') { // ??? | |
$from->send('Welcome to ' . $from->WebSocket->Router->path); | |
} | |
public function onMessage(ConnectionInterface $from) { | |
} | |
public function onClose(ConnectionInterface $conn) { | |
} | |
public function onError(ConnectionInterface $conn, \Exception $e) { | |
} | |
} |
I needed the routing feature, but this doc is very out-of-date and most of the classes don't exist anymore. I did lots of digging through the code, the tests, and the symfony routing components to finally come up with an example that actually works. I did have to do something weird though, and I don't know if that is because things just don't line up anymore, or because I'm missing something (my example works though).
The issue I ran into is that my first attempts with the Router ran but didn't work - the clients would complain that the connection was never established. After more digging I learned that the actual establishment of the connection happens in the WsServer
class and isn't handled by the Router
. Perhaps the WsRouter
would provide this functionality, but in my verson (0.4.1
) it does not exist, nor does the WebSocket
class that is wrapped around the WsRouter
.
This meant that I needed the WsServer
class to get in the mix to properly establish connections (either that or add the connection management to my controller, but that would rather defeat the purpose). This means that the WsServer needed to be passed as the controller of the route. Unfortunately the WsServer
class needs to be given an instance of the MessageComponentInterface
class (aka the class with my actual websocket functionality), but the router wants the controller class and will instantiate it itself. This means that the WsServer
cannot be passed in as a controller to the Router
, because there is no way to specify which MessageComponentInterface
implementer the WsServer
should use. To fix this I created a separate class for each of my MessageComponentInterface
classes which extends the WsServer
and manually instantiates the MessageComponentInterface
class and passes it into the WsServer
constructor. This worked.
This process was definitely fairly worky, but so far I love the interface/setup this project provides otherwise. Anyway, here's the working example:
<?php
// autoloading needs to go here
// require_once "../vendor/autoload.php";
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Psr\Http\Message\RequestInterface;
use Ratchet\Http\Router;
use Ratchet\Http\HttpServerInterface;
use Ratchet\ConnectionInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\HttpFoundation\Request;
class ChatServer extends WsServer {
public function __construct() {
parent::__construct(new Chat());
}
}
class Chat implements HttpServerInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) {
$this->clients->attach($conn);
print "\nConnection Opened!!!!";
$conn->send('welcome');
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
$client->send($msg);
}
}
public function onClose(ConnectionInterface $conn) {
}
public function onError(ConnectionInterface $conn, \Exception $e) {
}
}
$collection = new RouteCollection();
$collection->add('enroute', new Route('/enroute', [
'_controller' => ChatServer::class,
]));
$urlMatcher = new UrlMatcher($collection, new RequestContext());
$router = new Router($urlMatcher);
$server = IoServer::factory(
new HttpServer($router),
8080
);
$server->run();
@cmancone this is actually the only thing worked for me!
@cmancone Thanks man
Here is a working example for Laravel. My current version is 0.4.2.
https://gist.github.com/rahulhaque/2a92380e54779d03660e01da3851d24d
Does the App class of the ratchet not work anymore in version 0.4.4?
Here is a working example for Laravel. My current version is 0.4.2.
https://gist.github.com/rahulhaque/2a92380e54779d03660e01da3851d24d
Thank you man, searched all internet for a week!
This was on
0.3
, you should use like this in0.4
as the doc and app said.