I've been trying to run Ratchet.io over SSL (this problem: php ratchet websocket SSL connect?).
My webserver is running at myhost.mobi, and I have created a separate virtual host for websocket service "wws.myhost.mobi".
My web socket:
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0');
$webServer = new Ratchet\Server\IoServer(
new Ratchet\Http\HttpServer(
new Ratchet\WebSocket\WsServer(
new Ratchet\Wamp\WampServer(
$pusher
)
)
),
$webSock
);
My nginx config (I'm on nginx 1.5.8):
upstream websocketserver {
server localhost:8080;
}
server {
server_name wss.myapp.mobi;
listen 443;
ssl on;
ssl_certificate /etc/ssl/myapp-mobi-ssl.crt;
ssl_certificate_key /etc/ssl/myapp-mobi.key;
access_log /var/log/wss-access-ssl.log;
error_log /var/log/wss-error-ssl.log;
location / {
proxy_pass http://websocketserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect
proxy_redirect off;
}
}
My client-side script:
var conn = new ab.Session('wss://wss.myapp.mobi', function(o) {
// ...
}, function() {
console.warn('WebSocket connection closed');
}, {
skipSubprotocolCheck: true
});
So, when I load the page in Firefox, I see an outgoing connection to wss://wss.myapp.mobi:8080/, which is hanging (the spinner) and never completes or dies. I do not see any trace of request arriving on the backend in the logs.
What am I missing there?
Thanks!
EDIT I have realized that I should be connecting to wss://wss.myapp.mobi, but now I am getting "101 Switching Protocols" status.
EDIT 2 Everything is working now with the config above. "101 Switching Protocols" status turns out to be a normal message. PROBLEM SOLVED!
Have Nginx listen on port 80 for incoming connections and have it handle your SSL. Nginx will forward incoming connections to PHP-FPM for your regular website and if it detects a connection is a WebSocket connection have it proxy to your running Ratchet application on a port of your choice.
Here is a live example to show NGINX working as a WebSocket proxy. This example uses ws, a WebSocket implementation built on Node.js. NGINX acts as a reverse proxy for a simple WebSocket application utilizing ws and Node.js.
The problem is that React (which Ratchet is built on) does not support direct SSL connections. See this issue. There is a simple workaround. Use stunnel with a config like: Stunnel will handle SSL traffic on port 8443 and port them to your websocket server. Show activity on this post. The best solution would be to use Nginx as your web server.
Use stunnel with a config like: Stunnel will handle SSL traffic on port 8443 and port them to your websocket server. Show activity on this post. The best solution would be to use Nginx as your web server. Have Nginx listen on port 80 for incoming connections and have it handle your SSL.
By checking question edit history, it is clear that, the configuration in the question was correct, temuri was trying to connect from client with port set in,
upstream websocketserver {
server localhost:8080;
}
but this code block tells Nginx there is a tcp server running on port 8080, represents it as websocketserver
alias, but the running server is not accessible to public.
Check the below configuration,
server {
server_name wss.myapp.mobi;
listen 443;
ssl on;
ssl_certificate /etc/ssl/myapp-mobi-ssl.crt;
ssl_certificate_key /etc/ssl/myapp-mobi.key;
access_log /var/log/wss-access-ssl.log;
error_log /var/log/wss-error-ssl.log;
location / {
proxy_pass http://websocketserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect
proxy_redirect off;
}
}
this configuration binds the domain wss.myapp.mobi
to port 443 enabling ssl and proxy
ing the requests to the local websocket server via proxy_pass
directive, rest directives are for connection upgrades handling.
So the websocket server can be accessed from browser client with
// connect through binded domain
// instead of wss.myapp.mobi:8080 which will not work
var url = 'wss://wss.myapp.mobi';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With