Сбой WebSocket Proxy с Node.js и Angular.Неожиданный код ответа: 404 - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь набрать скорость при проксировании веб-сокетов.У меня есть некоторый угловой код, который я изменил из учебника, который проверяет соединения websocket с echo.websocket.org.Код работает сам по себе.

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      //var wsUri = "ws://localhost:8015"
      var output;
      var success = 0;
      var failure = 0;

      function init() {

        output = document.getElementById("output");
         output.innerHTML = "";
         testWebSocket();
         writeScore();

      }


      function testWebSocket() {
         websocket = new WebSocket(wsUri);

         websocket.onopen = function(evt) {
            onOpen(evt)
         };

         websocket.onclose = function(evt) {
            onClose(evt)
         };

         websocket.onmessage = function(evt) {
            onMessage(evt)
         };

         websocket.onerror = function(evt) {
            onError(evt)
         };
      }

      function onOpen(evt) {
         writeToScreen("CONNECTED");
         doSend("WebSocket rocks");
         success = success +1;
      }

     function onClose(evt) {
         writeToScreen("DISCONNECTED");
      }

      function onMessage(evt) {
         writeToScreen('<span style = "color: blue;">RESPONSE: ' + 
            evt.data+'</span>'); websocket.close();
      }

      function onError(evt) {
         writeToScreen('<span style = "color: red;">ERROR:</span> '
            + evt.data);
        failure = failure +1;
      } 

      function doSend(message) {
         writeToScreen("SENT: " + message); websocket.send(message);
      }

      function writeToScreen(message) {
         var pre = document.createElement("p"); 
         pre.style.wordWrap = "break-word"; 
         pre.innerHTML = message; 
         output.appendChild(pre);
      }

        function writeScore(){

        var pScore = document.createElement("p");
        pScore.style.wordWrap = "break-word";
        pScore.innerHTML = "Success   "+ success+ "   Failures   "+ failure;
        output.appendChild(pScore);

        }

      window.addEventListener("load", init, false);
   </script>

   <h2>WebSocket Test</h2>
   <div id = "output"></div>

</html>

, следуя инструкциям из https://github.com/nodejitsu/node-http-proxy#proxying-websockets

Я попытался установить простой прокси-сервер 2 различными способами, которые будут перенаправлять угловую страницуwebsocket запрашивает одно и то же соединение echo.websocket.org, изменив переменную wsUri в угловом коде так, чтобы она указывала на один из серверов, созданных в этом коде.

///
// Setup our server to proxy standard HTTP requests
//

var httpProxy = require('http-proxy');
var http = require('http');

var proxy = new httpProxy.createProxyServer({
  target: {
    host: 'echo.websocket.org',
    port: 80
  }
});


var proxyServer = http.createServer(function (req, res) {
  proxy.web(req, res);
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
        console.log(socket);
        proxy.ws(req, socket, head);
});


proxyServer.listen(8015);

var test = httpProxy.createServer({
  target: 'ws://echo.websocket.org',
  ws: true
});

test.listen(8014);

К сожалению, прокси-запрос (для обоих серверовпрослушивание портов 8014 и 8015) запускает угловой обработчик событий websocket.onerror, предоставляя мне менее полезное сообщение «undefined» для evt.data.

Обновление:

Chrome отображает следующую ошибкусообщение в инструментах разработчика, когда я пытаюсь открыть веб-страницу с помощью прокси-серверов localhost.

index.htm: 29 Ошибка подключения WebSocket к 'ws: // localhost: 8015 /': ошибка при рукопожатии WebSocket: неожиданный код ответа: 404

Отображение Firefoxв «Веб-консоли»:

Firefox не может установить соединение с сервером по адресу ws: // localhost: 8015 /.

Однако обновлениесобытие запускается, поскольку я вижу, как консоль узла отображает информацию о сокете из строки console.log () кода JS узла.Это наводит меня на мысль, что локальный сервер найден, поэтому возникает вопрос об источнике ошибки 404.Я не уверен, связано ли это с поиском прокси-сервера (для которого инициировано событие обновления http) или с целью прокси.

Как заставить Node JS прокси-сервер для углового соединения с веб-сокетом, который прекрасно работает, когда прокси-сервер не находится между браузером и echo.websocket.org?

1 Ответ

0 голосов
/ 01 июня 2018

TLDR;это связано с настройкой заголовка Host: foo.com перед отправкой прокси-запроса.

По сути, Error during WebSocket handshake: Unexpected response code: 404 означает, что он фактически не может установить соединение с данным wsUri.

Как видно из этого выпуска , changeOrigin предлагается по умолчанию true.

Однако в нашем случае это false (по умолчанию).Таким образом, перенаправленный запрос недействителен / неправильно сформирован без правильной настройки заголовка HTTP Host. Вы можете попытаться отладить это далее, чтобы увидеть реальные атрибуты HTTP, заголовки и т. Д.

Кроме того, атрибут

autoRewrite перезаписывает расположение узла /Порт на (201/301/302/307/308) перенаправляет на основе запрошенного хоста / порта.

Попробуйте добавить свойства ниже как createServer() аргументы:

autoRewrite: true,
changeOrigin: true,

Итак, это становится:

const test = httpProxy.createServer({
  target: 'ws://echo.websocket.org',
  ws: true,
  autoRewrite: true,
  changeOrigin: true,
});

test.listen(8014);

Надеюсь, это поможет!

...