neroxt
@neroxt
Программист

Как в Nginx спроксировать на другой порт WebSocket's?

На сервере есть приложение, слушает порт 7777 и ждет подключение по ws://

Коротко о том как должно работать:
Браузер -> Nginx(HTTPS) -> WS Сервер (тут мы хотим не использовать сертификат, из-за чего и такие заморочки)
Проблема в том, что по какой-то причине при отправлении данных на сервер приходит только часть сообщений из JS:

5c048a45c9fb9864508454.png5c048a6e06b19184349849.png

Всегда приходит 1 буква от сообщения, что очень странно.
Попробовал запустить все то же на локальной Windows машине, все работает как надо.

Запускал на c# с помощью websocket-sharp

WebSocketServer srv = new WebSocketServer(7777);
    srv.AddWebSocketService<MyClient>("/ws");//сюда должен перенаправлять proxy_pass
    srv.Start();
    Console.WriteLine("Server is listening......");

    //простой listener с выводом данных
    class MyClient : WebSocketBehavior
    {

        protected override void OnOpen() {  Write("Client Connected!", ConsoleColor.Green); }
        protected override void OnClose(CloseEventArgs e) {  Write("Close connection: "+ e.Reason, ConsoleColor.Red); }
        protected override void OnError(ErrorEventArgs e) { Write("Error: "+e.Message, ConsoleColor.DarkRed, ConsoleColor.Gray);  }
        protected override void OnMessage(MessageEventArgs e) { Write(e.Data); }
     }


Простой JS клиент:

var socket = new WebSocket("wss://мой-сайт/Game");
		socket.onopen = function() {
		   console.log("Соединение установлено.");
		   			activeBtns(false);
		};

		socket.onclose = function(event) {
		  if (event.wasClean) {
			 console.log('Соединение закрыто чисто');
		  } else {
			 console.log('Обрыв соединения'); // например, "убит" процесс сервера
		  }
		   console.log('Код: ' + event.code + ' причина: ' + event.reason);
			activeBtns(true);
		};

		socket.onmessage = function(event) {
		   console.log("Получены данные ");
		   console.log(event.data);
		};

		socket.onerror = function(error) {
		   console.log("Ошибка " + error.message);
			activeBtns(true);
		};
		activeBtns();
		sendData = function(){
			socket.send("test message");
		};


На сервере(OS: Ubuntu) есть Nginx с настройками(устанавливал чистый v1.14.1):

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

http {
	sendfile on;
	keepalive_timeout 604800;
	proxy_connect_timeout 604800;
	proxy_send_timeout 604800;
	proxy_read_timeout 604800;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

#конфиг моего домена:
server {
	listen       443 ssl;
	server_name  мой-сайт; #тут мой домен
	
	access_log /etc/nginx/logs/log.access;
	error_log /etc/nginx/logs/log.error error;
	 
	ssl on;
	ssl_certificate /etc/ssl/certs/cert.pem;
	ssl_certificate_key /etc/ssl/private/cert.key;

	client_max_body_size 1M;
	client_body_buffer_size 1M;

	location / {
	    root /var/www/мой-сайт/html;
	    index  index.html index.htm;
	}

	location /Game {
		proxy_pass  http://мой-сайт:7777/ws;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";

	}
}
  • Вопрос задан
  • 282 просмотра
Решения вопроса 1
neroxt
@neroxt Автор вопроса
Программист
Проблема в сервере, пока не знаю в чем конкретно, но поставив node.js все заработало
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
dasha_programmist
@dasha_programmist
ex Software Engineer at Reddit TS/React/GraphQL/Go
у меня вот так работает, но только сервер на Go:
map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
}
location = /ws {
            proxy_pass http://api-server:8088/ws;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы