Apache reverse proxy for websocket doesn't working - laravel

I have an issue with my WebSocket setup with Laravel and Apache (cPanel installed apache for me).
I'm using a reverse proxy to proxy requests from MY_DOMAIN/socket.io/ to localhost:6001/socket.io and I'm using mod_proxy_wstunnel too.
It was Ok and was running till yesterday and suddenly, it stopped working! Now I'm getting 301 status and nothing else!
I'll share my ws.conf file, my echo server configuration, and, my client-side code with you right below:
ws.conf
ProxyRequests off
ProxyVia on
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
<Location /ws/>
ProxyPass http://localhost:6001/socket.io
ProxyPassReverse http://localhost:6001/socket.io
Order allow,deny
Allow from all
</Location>
laravel-echo-server.json
{
"authHost": "https://MY_DOMAIN",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "e6c23c397d39255d",
"key": "feb9d433ee789dsc14a536d9l33575a01"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
"http": true,
"redis": true
},
"apiOriginAllow": {
"allowCors": false,
"allowOrigin": "",
"allowMethods": "",
"allowHeaders": ""
}
}
client-side code:
import Echo from 'laravel-echo';
if(window.Laravel){
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.Laravel.wsurl, // (I'm setting it in blade)
disableStats: true,
path: '/ws/',
enabledTransports: ['ws'],
transports: ['websocket', 'polling', 'flashsocket'],
csrfToken: window.Laravel.csrfToken
});
}
I have to add, server resources are something like this:
RAM: 64GB (used: 7GB and the rest of it is free)
CPU: AMD5-3600
H.D.D: 240 GB (used: 10GB)
I'll be appreciated any response. :)

Related

Laravel-echo-server and socket.io-client does't work on server

I use laravel echo server and socket.io-client and running at localhost is work at port 6001 and I config at server and use port 8443. Events and laravel echo server work but when client side connect, got 200 success and Remote Address: ip:443 instead of ip:8443.
laravel 7.0
laravel-echo-server 1.6.3
socket.io-client 2.3.0
NginxConfig
location /abc/projectpath{
proxy_pass https://blah.com/abc/projectpath:8443;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
root /var/www/html/abc/projectpath/public;
index index.php;
try_files $uri $uri/ /abc/projectpath/server.php$is_args$args;
#limit_conn conn_limit_per_ip 5;
}
Laravel Echo Server
{
"authHost": "https://blah.com/abc/projectpath",
"authEndpoint": "/broadcasting/auth",
"clients": [],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true,
"host": null,
"port": "8443",
"protocol": "https",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "sslpath",
"sslKeyPath": "sslkeypath",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
"http": true,
"redis": true
},
"apiOriginAllow": {
"allowCors": false,
"allowOrigin": "",
"allowMethods": "",
"allowHeaders": ""
}
client side
window.io = require('socket.io-client')
window.Echo = new Echo({
broadcaster: 'socket.io',
path: '/abc/projectpath:8443/socket.io',
host: 'https://blah.com'
})

Connection timed out Laravel-echo-server

I know and I have seen this question
Getting ERR_CONNECTION_TIMED_OUT Laravel echo server
But I tried the solution in comment but it doesn't work.
I have my Laravel-echo-server.json
{
"authHost": "https://mysite.it",
"authEndpoint": "/broadcasting/auth",
"clients": [],
"database": "redis",
"databaseConfig": {
"redis": {
"host":"0.0.0.0",
"port":"6379",
"password": "mypwd"
},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true,
"host": null,
"port": "6001",
"protocol": "https",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "path_cert" ,
"sslKeyPath": "path_key" ,
"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-IdOrigin, Content-Type, X-A uth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-IdOri gin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF -TOKEN, X-Socket-Id"
}
}
And I have in my bootstrapjs the connection with Frontend:
import Vue from 'vue'
import Echo from 'laravel-echo'
window.io = require('socket.io-client')
export var echo_instance = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001',
auth: {
headers: {
'Authorization': "Bearer " + localStorage.getItem('token')
}
}
})
Vue.prototype.$echo = echo_instance
export default Vue
I have check if the port was closed but with netstat -an I can see:
tcp6 0 0 :::6001 :::* LISTEN
But when I try to launch my app i receive:
app.js:569 GET
https://mysite.it:6001/socket.io/?EIO=3&transport=polling&t=NKoWZoK
net::ERR_CONNECTION_TIMED_OUT
How can I use the laravel echo with https protocol?
this might be because you have the wrong access token(dynamically added). why don't you try using a static access token first (copy the access token and paste it instead of localStorage.getItem('token')) for the user and see if it works.
Also try putting the following in laravel-echo-server.json file
"allowOrigin": "http://mysite.it:80"
And, see if APP_URL is different in .env file

WebSocket connection to 'wss://***:6001/socket.io/?EIO=3&transport=websocket' failed: WebSocket is closed

I'm using laravel. I want to connect a socket connection on SSL.
Echo Version: 1.6.2
Laravel Version: 5.7.28
PHP Version: 7.2.31
NPM Version: 6.14.5
Node Version: 11.15.0
I'm using a SSL protocol.
I got this error message from frontend:
WebSocket connection to 'wss://example.com:6001/socket.io/?EIO=3&transport=websocket' failed: WebSocket is closed before the connection is established
this is my laravel-echo-server.json
{
"authHost": "https://example.com",
"authEndpoint": "/broadcasting/auth",
"clients": [],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true,
"host": null,
"port": "6001",
"protocol": "https",
"socketio": {},
"secureOptions": ****,
"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"
}
}
And my apache2 config:
<VirtualHost *.*.*.*:80>
ServerName example.com
ServerAlias mail.example.com www.example.com
DocumentRoot /home/example/public_html
ServerAdmin webmaster#example.com
UseCanonicalName Off
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
## User example # Needed for Cpanel::ApacheConf
<IfModule userdir_module>
<IfModule !mpm_itk.c>
<IfModule !ruid2_module>
<IfModule !mod_passenger.c>
UserDir disabled
UserDir enabled example
</IfModule>
</IfModule>
</IfModule>
</IfModule>

Laravel echo server won't start

Laravel echo server keeps returning failed status on my server
Code
laravel-echo-server.json
{
"authHost": "http://example.com",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "311dr094tf98745ce",
"key": "fa43bffb3rth63f5ac9c386916ae28e6"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
"http": true,
"redis": true
},
"apiOriginAllow": {
"allowCors": true,
"allowOrigin": "http://localhost:80",
"allowMethods": "GET, POST",
"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
}
}
echo-pm2.json
{
"name": "echo",
"script": "laravel-echo-server.json",
"args": "start"
}
then i run pm2 start echo-pm2.json and status is online but when i visit my web page i keep getting
GET https://www.example.com:6001/socket.io/?EIO=3&transport=polling&t=NA2SNHk net::ERR_TIMED_OUT
Any idea?
"authHost": "http://example.com"
I have this set to the url of my localhost, not sure if it helps you
Solved
The problem was my url was set to https (GET https://www.example.com) while my actual address is running on http (GET http://www.example.com)
so that extra S... :)

Configuring Apache Reverse Proxy For Hosting Laravel Echo Server On Production

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.

Resources