skip to Main Content

I wrote a php websockets server using the library Ratchet that I call with javascript using the websocket object.

Everything worked perfectly locally but it was impossible to run my project on my Debian server under apache.

To enable websocket connections I read that I have to use mod_proxy_wstunnel module. So I rewrite my apache conf for my subdomain api.domain.com like this:

<VirtualHost *:80>
        ServerAdmin [email protected]
        DocumentRoot /var/www/api.domain.com
        ServerName api.domain.com

        # Enable Websocket connections on port 8888
        ProxyPass "/wss/homews/" "ws://api.domain.com:8888/"

        <Directory /var/www/api.domain.com>
                Options FollowSymLinks
                AllowOverride All
                Order allow,deny
                Allow from all
                Satisfy all
        </Directory>
</VirtualHost>

Then I call my php script with this code insight that start Ratchet websocket server:

// ...
// Some code ...
$app = new RatchetApp('localhost', 8888);
$app->route('/wss/homews/', $myClass, array('*'));
$app->run();

Then when I try to connect to it on the javascript client side with the url ws://api.domain.com:8888/wss/homews/ I always get Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT.

Do you have any ideas how I could debug this type of error ? Are there any logs on apache showing a bad configuration?

2

Answers


  1. First and foremost, try to simplify things, DO NOT edit or touch any of the configuration files from the server, leave it by default as it is, that will do

    I will post all the precautions steps needed in order make the socket up and running, please follow steps one by one, they are as follows:

    1. Check whether your server supports Web Socket on shared hosting, otherwise you may need to go for Dedicated hosting service or Virtual private server(VPS) Eg: AWS, GCP.
      If your server supports running a web service scripts like phpwebsocket within a web service, then follow next steps

    2. On the terminal, Update the composer to the latest one, then try to execute $composer require cboden/ratchet
      So that the required dependency will load efficiently and do not try to upload any archived dependencies.
      In my case, "cboden/ratchet": "^0.4.3" was loaded on localhost, But on production site it was "cboden/ratchet": "^0.4.1"
      when compared both from the composer.json file

    3. Try to connect to port 8282, In most cases, the server traffic, both from the inbound & outbound are kept open by default, in case, if the port 8080, could not bind to the TCP

    4. At Last, Try to reboot your cloud hosted server instance and execute the websocket script $php <yourWebSocketScript.php>

    I had used mod_proxy_wstunnel to make sure the communications goes encrypted, apart from it,
    I was able to up & run the Websocket socketo.me on AWS and our private dedicated server smoothly

    Thanks for contacting, I do appreciate your efforts, apart from your concerned comment to reply via johannchopin@protonmaildotcom, this is not my part of the business ethics


    Edit

    $app = new RatchetApp('localhost', 8888);
    $app->route('/wss/homews/', $myClass, array('*'));
    $app->run();
    

    Try changing the manually assigned localhost from your <yourWebSocketScript.php> from the above snippet to

    $app = IoServer::factory(
        new HttpServer(new WsServer(new Chat())),
        8282
    );
    $app->run();
    

    Try binding to the HttpServer, it defaults to localhost or 0.0.0.0 and run (if necessary, eliminate $app->route())

    On your code you need to modify

    1. Port Number in yourWebSocketScript.php

    2. Change from localhost to the Server IP or DNS in someChatFilexyz.php

        Eg:
        let websocket_server = new WebSocket("ws://my.domain.com:8282");
        or
        let websocket_server = new WebSocket("ws://xxx.xxx.xxx.xxx:8282");
    
    1. Kill all the previous established socket specific to port 8282 and then run yourWebSocketScript.php

    Here is the partial code of someChatFilexyz.php

    jQuery(function($){
    // Websocket_Controller
    var websocket_server = new WebSocket("ws://xxx.xxx.xxx.xxx:8282");
    websocket_server.onopen = function(e) {
    websocket_server.send(
    ...
    );
    };
    
    websocket_server.onerror = function(e) {
    // Errorhandling
    ...
    }
    
    websocket_server.onmessage = function(e) {
    
    ...
    }
    }
    

    Setting up the above config, I was able to run on an Amazon Web Service with LAMP stack configured by me and with private dedicated server with ease.

    Note: Any minor changes in the code, you need to restart the running websocket script $php <yourWebSocketScript.php> i.e., either by terminating the running process or killing the process specific to port number assigned

    Login or Signup to reply.
  2. Your above configuration has to be changed at least to:

    <VirtualHost *:80>
            ServerAdmin [email protected]
            DocumentRoot /var/www/api.domain.com
            ServerName api.domain.com
    
            # Enable Websocket connections on port 8888
            ProxyPass "/wss/homews/" "ws://localhost:8888/wss/homews/"
    
            <Directory /var/www/api.domain.com>
                    Options FollowSymLinks
                    AllowOverride All
                    Order allow,deny
                    Allow from all
                    Satisfy all
            </Directory>
    </VirtualHost>
    

    And on the javascript client side to the url ws://api.domain.com:80/wss/homews/.

    Otherwise probably (or lets say hopefully for a server setup) the target from webserver config api.domain.com:8888 tries to reach upstream the websocket on public IP of the server while websocket is bound to localhost. Eighther it’s just not listening there (what is fine as You nromally only want to expose Your webservers ports to the public and not directly Your app ports) or even worse it tries to reach a public NAT IP which involves a trip to a firewall where the port 8888 should be blocked, which may not allow this stuff, can be expensive (eg. AWS EC2) and ist at very least inperformant.

    On the other hand You will want to direct the client code to the webserver on port 80 which does the tunnelling to Your websocket app so Your client cannot directly access port 8888 of Your server (it’s blocked in the public firewall hopefully – and You are listening on localhost only).

    Try with Your original setup and tell how the results changed, maybe there is an additional issue (but You should not get a socket timeout anymore at least and a connection from client to websocket app).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search