Search code examples
javascriptphpapachewebsocketratchet

How to configure WebSocket with Apache + Ratchet + SSL + Laravel?


I have a problem with a websocket server. It's also my first time with this tech.

I'm using:

  • Apache
  • Ratchet (PHP)
  • SSL (HTTPS on 443 as usual)
  • There is also a Laravel server, which probably change the configuration of the server. Do I need to modify the path of my server or not? (I really don't know much in Apache settings).

I was using this source to make my configuration (it's in French).

But I can't connect to my websocket from client with js. I'm still getting this error:

WebSocket connection to 'wss://server_name.fr/ws/game' failed

Here is my config file for my site:

<VirtualHost server_name.fr:443>
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/server_name/public/
        <Directory /var/www/html/server_name/>
                AllowOverride All       
        </Directory>

        <Location "/ws/game">
                ProxyPass wss://localhost:1176
                ProxyPassReverse wss://localhost:1176
        </Location>

The JavaScript:

var conn = new WebSocket('wss://server_name.fr/ws/game');
conn.onopen = function(e) {
    console.log("Connection established!");
};

conn.onmessage = function(e) {
    console.log(e.data);
};

The PHP Server that I'm running on port 1176 (Almost exactly the example):

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

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

define('APP_PORT', 1176);

class ServerGame implements MessageComponentInterface
{
    protected $lobby;
    protected $rooms;
    protected $client_in_room;

    public function __construct()
    {
        $this->lobby = array();
    }

    public function onOpen(ConnectionInterface $conn)
    {

    }

    public function onMessage(ConnectionInterface $conn, $msg)
    {

    }

    public function onClose(ConnectionInterface $conn)
    {

    }

    public function onError(ConnectionInterface $conn, \Exception $e)
    {

    }
}

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new ServerGame()
        )
    ),
    APP_PORT
);
echo "Server created on port " . APP_PORT . "\n\n";
$server->run();

Thanks for your help!


Solution

  • I found the problem. I try again without Laravel (wich should'nt be a problem even if it were there):

    I was using CHROME, and Chrome require to use the port 443 for wss. So I had to use this directive in my httpd conf :

    <VirtualHost my_site.fr:443>
        ProxyPass "/wss2/" "ws://localhost:1176/"
    

    And the JS File with the websocket connection :

    var conn = new WebSocket('wss://my_site.fr:443/wss2/');
    

    (For what I understand as a newbie in proxy) :

    The JS file will send a request using the wss protocole, this the "wss://" part, like "https://" is used for https etc.. So When the request get to apache. Apache will check wich directives are applied to it. So it will applied our directive above because :

    • It came from a url of the form "my_site.fr" on port "443"
    • Then it check inside the directive the actions to take. Such as :
    • Since the url point to a sub directory (my_site.fr:443/wss2/), it "proxy" the request to a localhost request (wich google does'nt know, so it's allowed !) and you can make it point to whatever you want. (But keep it safe)

    The important part was to add the port in the js to keep it on 443

    And then it should work !