Answer the question
In order to leave comments, you need to log in
How to make socket.io proxy work through nginx on Ubuntu?
Hello. There is a site located on a local server on Ubuntu 18.04. Powered by nginx + php-fpm + node.js to run interactive elements via socket.io. Versions: nginx 1.14.0, node.js 8.10.0, the rest is probably not important.
Trying to set up a socket.io (node.js) proxy via nginx. Everything seems to be done correctly, and, of course, nothing works. The browser does not display any errors, the node also does not pretend that it is receiving socket connections.
The node works great without a proxy. But you can’t do without a proxy, since there will be ssl, and if node.js and nginx work independently, then the browser assumes that https://site.local and https://site.local:3000are different origins, even if I pass the 'Access-Control-Allow-Origin: *' header, and it doesn't let me connect to the node. Self-signed certificates for tests, but even if you turn off ssl everywhere, there is no result.
Question: what kind of roller to drive through all this so that it starts working as it should? I immediately warn you that I am not strong in Ubuntu and nginx, and I ask for detailed answers on what and where to change.
Update 1
Changed location for socket access from /ws/ to /socket.io/. Also replaced in the question. Emits began to come to the node when the client disconnected. Any other emits still fail. Temporarily disabled https on nginx and enabled error logging. This error pops up several times:
2019/01/19 00:47:11 [error] 18590#18590: *4011 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: site.local, request: "GET /socket.io /?EIO=3&transport=polling&t=MXYxf2D HTTP/1.1", upstream: " 127.0.0.1:3000/?EIO=3&transport=polling&t=MXYxf2D ", host: "site.local", referrer: " site.local/tasks "
2019/01/19 00:47:12 [error] 18590#18590: *4011 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: site.local, request: "GET /socket.io/?EIO=3&transport=polling&t=MXYxg6A HTTP/1.1", upstream: " 127.0.0.1:3000/?EIO=3&transport=polling&t=MXYxg6A ", host: "site.local",referrer: " site.local/tasks "
# ...
upstream nodejs # типа переменной, содержащей адрес сервера с нодой
{
ip_hash;
server localhost:3000; # пытался менять порты, писать адрес сайта напрямую и ip, бесполезно
}
server
{
# Порт, SSL и ключи, сервер, директория
listen 443 ssl;
ssl_certificate /home/user/sites/site.local/ssl/server.crt;
ssl_certificate_key /home/user/sites/site.local/ssl/server.key;
server_name site.local;
root /home/user/sites/site.local;
index index.php;
# ...
# Пытаемся открыть путь, как файл, как каталог, и если нет, то перенаправляем на index.php
location /
{
try_files $uri $uri/ /index.php?$query_string;
}
# Подключение php-fpm
location ~* \.php$
{
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
# Прокси socket.io (https://site.local/socket.io/)
location /socket.io/
{
# Перенаправление на upstream nodejs из начала листинга
proxy_pass http://nodejs;
# Тут по-всякому игрался, никакого толка
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# ...
}
// ...
// Инициализация сервера, тут вроде ок
var http = require ('http');
var io = require ('socket.io');
var app = http.createServer ().listen (3000);
var io = io.listen (app);
// ...
// Пункты назначения после проксирования, до которых ничего не доходит
io.sockets.on ('connection', function (socket)
{
// Авторизация
socket.on ('Auth_Request', function (data)
{
console.log ('какого чёрта не выводится консоле.лог?');
});
// Отключение
socket.on ('disconnect', function ()
{
console.log ('аналогично');
});
// ...
});
// ...
Answer the question
In order to leave comments, you need to log in
Long story short, I messed around. And I managed to get it to work with Nginx, but only by creating a "namespace" forcibly.
On the client, the connection request looks like this
on the server:
var io = require('socket.io')(3001); // спицально ему другой порт прикрутил, для "чистоты эксперимента"
var chat = io.of('/sock');
chat.on('connection', socket => { ...
io = io.of('/sock');
). location /sock {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001/sock;
}
I'm not sure, but you have location /ws. Try /socket.io
Why doesn't socket.io work on nginx?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question