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.
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.