S
S
sorokinfil2019-01-18 18:32:43
Nginx
sorokinfil, 2019-01-18 18:32:43

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 "

Code from /etc/nginx/sites-available/site.local:
# ...

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;
  }

  # ...

}

Code from server.js (Node.js)
// ...

// Инициализация сервера, тут вроде ок
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

2 answer(s)
A
Abcdefgk, 2019-01-19
@sorokinfil

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

and then wherever there was io in the code - replace it with the chat variable - like chat.to(socket.id).emit... etc. (although, apparently, it was possible to simply override io: io = io.of('/sock');).
And finally, Nginx redirects it like this
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;
        }

So everything got screwed up.

Y
Yuri Kizilov, 2019-01-18
@Kizilov

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 question

Ask a Question

731 491 924 answers to any question