Reputation: 149
I am trying to run NodeJS behind Apache and so far I am stuck with Socket.io issue.
I have no issue accessing the application directly, but whenever I accessed through my domain, I get this error thrown from socket.io:
Firefox can’t establish a connection to the server at wss://example.com/socket.io/?EIO=3&transport=websocket&sid=X-hLU73t7ojk2zoRAAAB.
My Apache configuration is as follows:
<VirtualHost _default_:443>
ServerName example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
ProxyRequests off
ProxyVia on
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
ProxyPass /socket.io http://localhost:8080/socket.io
ProxyPassReverse /socket.io http://localhost:8080/socket.io
<Location />
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse http://127.0.0.1:8080/
</Location>
#ProxyPass / http://localhost:8080/
#ProxyPassReverse / http://localhost:8080/
# BrowserMatch "MSIE [2-6]" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
I have also tried changing the RewriteRule /(.*)
to wss://localhost:8080/$1 [P,L]
but still thrown the same error. Can't seem to find any other answer to solve this.
I believe I am using socket.io 2.0, and on the client side it is connected as such:
var socket = io();
This is what bugs me,
It seems that some of the connection is going through but one is not.
Upvotes: 2
Views: 16712
Reputation: 663
What I have could be slightly different and I've found that some solutions don't apply in every situation. Here is what I have with Apache as reverse proxy and works for me (with https).
Server: server.js
const express = require('express');
const app = express();
const http = require("http").createServer(app);
socketio = require("socket.io")(http);
const socket_port = 5003;
// @ Start server
http.listen(socket_port , () => console.log('Socket server served on port: ' + socket_port));
Apache config below.
Add ProxyPass and websocket upgrade as below. Include it at the bottom of your virtualhost configuration.
<VirtualHost *:443>
# ...
# ...
# Add at the end of conf
ProxyPass / http://localhost:5003/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.*) http://localhost:5003/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.*) http://localhost:5003/$1 [P,L]
</VirtualHost>
Client client.js
Connect from NodeJS client application. Supports other clients like Flutter app etc.
var ios = require('socket.io-client');
const externalServerAdress = "https://YOUR-DOMAIN-HERE";
var socketClient = ios.connect(externalServerAdress, {
reconnect: true,
secure: true,
rejectUnauthorized : false,
});
socketClient.on('connect', function (socket) {
console.log('This client is connected to ' + externalServerAdress + '
server with ID: ' + socketClient.id);
// your rest of awesome code here
});
Follow this thread where I described how ti implement it with https and Apache proxy upgrade. https://github.com/rikulo/socket.io-client-dart/issues/319
Upvotes: 0
Reputation: 503
Using Apache 2.4.6 on Centos 7
You need to do two things, first, on client-side initiate the socket-io in the following way:
var socket_io = io(wss://YOUR-IP/,{
path: '/monitor-01',
transports: ['websocket']
});
Then, on the apache side, you must do the following configuration:
<VirtualHost *:443>
.
.
.
ProxyPass /monitor-01 ws://localhost:4000/socket.io
ProxyPassReverse /monitor-01 ws://localhost:4000/socket.io
</VirtualHost>
With these configurations you may have also, multiple socket connections on the same server, and for different applications.
Upvotes: 0
Reputation: 341
Look into setting up a connection upgrade in Apache. That's what I needed to config nginx. Also, those http requests could be socketio serving the client file.
Also look into this: http://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
Edit:
The issue was solved with passing the ws/wss proxy as stated in mod_proxy_wstunnel. The apache virtual host config should have this:
ProxyPass /socket.io/ ws://localhost:8080/socket.io
ProxyPassReverse /socket.io/ ws://localhost:8080/socket.io
Instead of this:
ProxyPass /socket.io http://localhost:8080/socket.io
ProxyPassReverse /socket.io http://localhost:8080/socket.io
Upvotes: 10