5

I need to host a laravel application that utilizes laravel-echo-server over a HTTPS server.

I want to use Apache's reverse proxy to redirect my /socket.io url polls to 127.0.0.1 on port 6001 which is where laravel-echo-server is running on within the same domain url.

For example over https://example.com when my laravel-echo-server sends url polls to https://example.com/socket.io apache should redirect it to http://127.0.0.1:6001 within that same domain.

NOTICE

I'm not hosting my laravel app at the root directory but in a subdirectory within my cpanel.

My server is a VPS and I am hosting from a sub domain host that runs on a separate IP address from that of the main server host.

Let's say my main host is host.mydomain.com with a unique IP address pointing to the /home/... directory. This runs on http

I now have a domestic.mydomain.com with a unique IP address pointing to the /home/domestic/... directory and this is where I'm hosting my laravel app from. This runs on https.

But my cpanel login is from the host.mydomain.com IP address where i access the domestic.mydomain.com file manager

What my laravel-echo-server.json looks like:

{
    "authHost": "https://example.com",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        {
            "appId": "xxxx",
            "key": "xxxxxxxx"
        }
    ],
    "database": "redis",
    "databaseConfig": {
        "redis": {},
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": false,
    "host": "127.0.0.1",
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "subscribers": {
        "http": true,
        "redis": true
    },
    "apiOriginAllow": {
        "allowCors": false,
        "allowOrigin": "",
        "allowMethods": "",
        "allowHeaders": ""
    }
}

How I deploy my laravel-echo:

import Echo from "laravel-echo";
window.io = require('socket.io-client');
// Have this in case you stop running your laravel echo server
if (typeof io !== 'undefined') {
  window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname,
  });

  window.Echo.channel('session-expired')
  .listen('sessionExpired', (e) => {
    setTimeout(location.reload(), 3000);
  });
}

And when I run laravel-echo-server start It successfully initialises and shows running on 127.0.0.1 on port 6001

Then here is my apache reverse proxy config /etc/httpd/conf/httpd.conf:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
# mod_proxy setup.
ProxyRequests Off
ProxyPass /socket.io http://127.0.0.1:6001
ProxyPassReverse /socket.io http://127.0.0.1:6001
<Location "/socket.io">
  Order allow,deny
  Allow from all
</Location>

My problem is when I open my website the polls return a set of OK and 404 responses simultaneously, but it doesn't join any channels within my socket.io. After lots of testing i figured that the proxy does redirect but i doubt it's hitting the particular one I want.

Heres the HTML responses for my 404, which is not my server's configured 404 response:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /</pre>
</body>
</html>

It runs perfectly on my local server but I need to make it run on my production server.

Ikechukwu
  • 1,135
  • 1
  • 13
  • 30

1 Answers1

2

Finally got it.

While my website must still bear an SSL, the solution is to get Apache to redirect /socket.io to http://localhost:6001/socket.io already configured for redis. Then use 2.2.3 version of socket io.

So my laravel-echo-server.json isn't configured for SSL.

Heres my laravel-echo-server.json:

{
   "authHost": "https://domainName.com",
   "authEndpoint": "/broadcasting/auth",
   "clients": [
      {
        "appId": "xxxxxxx",
        "key": "xxxxxxxxxxx"
      }
   ],
   "database": "redis",
   "databaseConfig": {
      "redis": {},
      "sqlite": {
          "databasePath": "/database/laravel-echo-server.sqlite"
      }
   },
   "devMode": false,
   "host": null,
   "port": "6001",
   "protocol": "http",
   "socketio": {},
   "sslCertPath": "",
   "sslKeyPath": "",
   "sslCertChainPath": "",
   "sslPassphrase": "",
   "subscribers": {
       "http": true,
       "redis": true
   },
   "apiOriginAllow": {
   "allowCors": true,
   "allowOrigin": "*",
   "allowMethods": "GET, POST",
   "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
}

}

How I utitlizes laravel-echo-server.json:

import Echo from "laravel-echo";
window.io = require('socket.io-client');
// Have this in case you stop running your laravel echo server
if (typeof io !== 'undefined') {
  window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname,
  });

}

And my apaxhe config within my SSL virtualhost for my domain:

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:6001/$1 [P,L]

ProxyPass        /socket.io http://localhost:6001/socket.io
ProxyPassReverse /socket.io http://localhost:6001/socket.io 

In addition it would require a Node js process manager to keep the laravel-echo-server running. So I created echo-server.json and placed the following code.

{
  "name": "apps",
  "script": "laravel-echo-server",
  "args": "start"
}

Next, I install pm2 process manager. npm install pm2 -g and started my service pm2 start echo-server.json --name="apps".

Lastly I use pm2 list to view all my services and pm2 startup to keep my services running.

Ikechukwu
  • 1,135
  • 1
  • 13
  • 30
  • Hey, could you help me please? I am struggling with it a lot :( So my laravel queue listener catches events, I see that memory usage is increasing in pm2 console, however, nothing works without any response – Tyoma Inagamov Apr 20 '21 at 16:04
  • I launched laravel-echo-server manually before and it didn't response. User never joined any channel – Tyoma Inagamov Apr 20 '21 at 16:05
  • Try using `socket io client 2.2.0` @TyomaInagamov – Ikechukwu Apr 22 '21 at 09:47
  • Didn't help( I am so tired of this problem.. Any other advice? @Ikechukwu – Tyoma Inagamov Apr 24 '21 at 17:54
  • I see that event is coming `php artisan queue:listen --timeout=0`, but it's not coming up at laravel-echo-server. Neither user joins his channel – Tyoma Inagamov Apr 24 '21 at 17:56
  • Please check out my config files: https://stackoverflow.com/questions/67179049/how-to-launch-laravel-echo-server-on-production – Tyoma Inagamov Apr 24 '21 at 18:01
  • @TyomaInagamov Firstly, this configuration is for `Apache` and not `nginx`. Secondly is it over a Private Channel? Try out a Public Channel and let's see. Finally,`laravel-echo-server` has only worked for me over version 2 of `socket io`. An issue has been opened on `GitHub` https://github.com/tlaverdure/laravel-echo-server/issues/559 – Ikechukwu Apr 25 '21 at 10:18
  • Yeah, I know that it's for `Apache`, however, in your example everything is the same (comparing to other configs) expect the configuration of `Apache`/`Nginx` – Tyoma Inagamov Apr 25 '21 at 11:15
  • I use Private Channel. With Public Channel the situation seems to be the same, not working( – Tyoma Inagamov Apr 25 '21 at 11:17
  • Changing the version didn't help either – Tyoma Inagamov Apr 25 '21 at 11:18
  • This is fantastic. The explanation is crystal clear. Thanks. – Arun Panneerselvam Oct 08 '22 at 15:05
  • I followed all your steps and for local this address I put it, but the error: GET https://kashef.tadbirserver.ir:6001/socket.io/socket.io.js net::ERR_CONNECTION_REFUSED Gives. If possible, guide me? – AliNasiri Oct 27 '22 at 06:49