Skip to content

Instantly share code, notes, and snippets.

@rahulhaque
Created June 25, 2020 10:56
Show Gist options
  • Select an option

  • Save rahulhaque/2a92380e54779d03660e01da3851d24d to your computer and use it in GitHub Desktop.

Select an option

Save rahulhaque/2a92380e54779d03660e01da3851d24d to your computer and use it in GitHub Desktop.

Revisions

  1. rahulhaque created this gist Jun 25, 2020.
    56 changes: 56 additions & 0 deletions CustomWebsocketOneController.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    <?php

    namespace App\Http\Controllers;

    use Ratchet\ConnectionInterface;
    use Ratchet\WebSocket\MessageComponentInterface;
    use React\EventLoop\LoopInterface;
    use SplObjectStorage;

    class CustomWebsocketOneController implements MessageComponentInterface
    {
    protected $clients;
    protected $loop;

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

    public function onOpen(ConnectionInterface $conn)
    {
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " Client connected to CustomWebsocketOneController " . $conn->resourceId . "\n";
    $this->clients->attach($conn);
    }

    public function onClose(ConnectionInterface $conn)
    {
    $this->clients->detach($conn);
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " => On close connection id " . $conn->resourceId . " \n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " => On error connection id " . $conn->resourceId . " \n";
    echo "*** " . $e->getLine() . ": " . $e->getMessage() . "\n";

    $this->clients->detach($conn);
    $conn->close();
    }

    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);
    }
    }
    }

    }
    56 changes: 56 additions & 0 deletions CustomWebsocketTwoController.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    <?php

    namespace App\Http\Controllers;

    use Ratchet\ConnectionInterface;
    use Ratchet\WebSocket\MessageComponentInterface;
    use React\EventLoop\LoopInterface;
    use SplObjectStorage;

    class CustomWebsocketTwoController implements MessageComponentInterface
    {
    protected $clients;
    protected $loop;

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

    public function onOpen(ConnectionInterface $conn)
    {
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " Client connected to CustomWebsocketTwoController " . $conn->resourceId . "\n";
    $this->clients->attach($conn);
    }

    public function onClose(ConnectionInterface $conn)
    {
    $this->clients->detach($conn);
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " => On close connection id " . $conn->resourceId . " \n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {
    echo date('Y-m-d H:i:s') . " line:" . __LINE__ . " => On error connection id " . $conn->resourceId . " \n";
    echo "*** " . $e->getLine() . ": " . $e->getMessage() . "\n";

    $this->clients->detach($conn);
    $conn->close();
    }

    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);
    }
    }
    }

    }
    80 changes: 80 additions & 0 deletions StartRatchetServer.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    <?php

    namespace App\Console\Commands;

    use App\Http\Controllers\CustomWebsocketOneController;
    use App\Http\Controllers\CustomWebsocketTwoController;
    use Illuminate\Console\Command;
    use Ratchet\Http\HttpServer;
    use Ratchet\Http\OriginCheck;
    use Ratchet\Http\Router;
    use Ratchet\Server\IoServer;
    use Ratchet\WebSocket\WsServer;
    use React\EventLoop\Factory as LoopFactory;
    use React\Socket\Server;
    use Symfony\Component\Routing\Matcher\UrlMatcher;
    use Symfony\Component\Routing\RequestContext;
    use Symfony\Component\Routing\Route;
    use Symfony\Component\Routing\RouteCollection;

    class StartRatchetServer extends Command
    {
    /**
    * The name and signature of the console command.
    *
    * @var string
    */
    protected $signature = 'ratchet:serve';

    /**
    * The console command description.
    *
    * @var string
    */
    protected $description = 'Start ratchet websocket server';

    /**
    * Create a new command instance.
    *
    * @return void
    */
    public function __construct()
    {
    parent::__construct();
    }

    /**
    * Execute the console command.
    *
    * @return mixed
    */
    public function handle()
    {
    $port = 6001;
    echo "Ratchet server started on localhost:{$port} \n";
    $address = '0.0.0.0'; // Client address to accept. (0.0.0.0 means receive connections from any)
    $loop = LoopFactory::create();
    $socket = new Server("{$address}:{$port}", $loop);
    $routes = new RouteCollection();

    echo "App route-one websocket running on localhost:{$port}/route-one \n";
    $customWebsocketOneServer = new WsServer(new CustomWebsocketOneController($loop));
    $customWebsocketOneServer->enableKeepAlive($loop); // Enable message ping:pong
    $routes->add('route-one', new Route('/route-one', [
    '_controller' => $customWebsocketOneServer,
    ]));

    echo "App route-two websocket running on localhost:{$port}/route-two \n";
    $customWebsocketTwoServer = new WsServer(new CustomWebsocketTwoController($loop));
    $customWebsocketTwoServer->enableKeepAlive($loop); // Enable message ping:pong
    $routes->add('route-two', new Route('/route-two', [
    '_controller' => $customWebsocketTwoServer,
    ]));

    $urlMatcher = new UrlMatcher($routes, new RequestContext());
    $router = new Router($urlMatcher);
    $checkedApp = new OriginCheck($router, ['localhost']);
    $server = new IoServer(new HttpServer($router), $socket, $loop); // Pass $checkedApp to filter origin
    $server->run();
    }
    }