Http-прокси Node.js отбрасывает запросы websocket

Хорошо, я'Мы потратили больше недели, пытаясь понять это безрезультатно, поэтому, если у кого-то есть подсказка, вы - герой. Это н'На этот вопрос будет нелегко ответить, если я не тупица.

Я использую node-http-proxy для прокси липких сессий 16 работникам node.js, работающим на разных портах.

Я использую Socket.IO 'Веб-сокеты для обработки множества различных типов запросов, а также для использования традиционных запросов.

Когда я переключил свой сервер на прокси через node-http-proxy, иногда возникала новая проблема: сеанс Socket.IO не может установить соединение.

Я буквально могуОн стабильно воспроизводит его всю жизнь, и единственный способ включить его - перебрасывать много трафика с нескольких клиентов на сервер.

Если я перезагрузить пользователяПосле этого браузер может иногда подключаться, а иногда нет.

Липкие Сессии

Я должен прокси-сеанс липких сессий, так как мое приложение проходит проверку подлинности для каждого сотрудника, и поэтому он направляет запрос на основе своего файла cookie Connect.SID (я использую Connect / Express).

Хорошо, немного кода

Это мой файл proxy.js, который работает в узле и маршрутизирует каждого из рабочих:

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

// What ports the proxy is routing to.
var data = {
  proxyPort: 8888,
  currentPort: 8850,
  portStart: 8850,
  portEnd: 8865,
};

// Just gives the next port number.
nextPort = function() {
  var next = data.currentPort++;
  next = (next > data.portEnd) ? data.portStart : next;
  data.currentPort = next;
  return data.currentPort;
};

// A hash of Connect.SIDs for sticky sessions.
data.routes = {}

var svr = httpProxy.createServer(function (req, res, proxy) {

  var port = false;

  // parseCookies is just a little function
  // that... parses cookies.
  var cookies = parseCookies(req);  

  // If there is an SID passed from the browser.
  if (cookies['connect.sid'] !== undefined) {

    var ip = req.connection.remoteAddress;

    if (data.routes[cookies['connect.sid']] !== undefined) {

      // If there is already a route assigned to this SID,
      // make that route's port the assigned port.
      port = data.routes[cookies['connect.sid']].port;
    } else {

      // If there isn't a route for this SID,
      // create the route object and log its
      // assigned port.
      port = data.currentPort;
      data.routes[cookies['connect.sid']] = {
        port: port,
      }

      nextPort();
    }

  } else {

    // Otherwise assign a random port, it will/
    // pick up a connect SID on the next go.
    // This doesn't really happen.
    port = nextPort();
  }

  // Now that we have the chosen port, 
  // proxy the request.
  proxy.proxyRequest(req, res, {
    host: '127.0.0.1',
    port: port
  });
}).listen(data.proxyPort);

// Now we handle WebSocket requests.
// Basically, I feed off of the above route
// logic and try to route my WebSocket to the
// same server regular requests are going to.
svr.on('upgrade', function (req, socket, head) {

  var cookies = parseCookies(req);  
  var port = false;

  // Make sure there is a Connect.SID,
  if (cookies['connect.sid'] != undefined) {

    // Make sure there is a route...
    if (data.routes[cookies['connect.sid']] !== undefined) {

      // Assign the appropriate port.
      port = data.routes[cookies['connect.sid']].port;
    } else {

      // this has never, ever happened, i've been logging it.
    }
  } else {

    // this has never, ever happened, i've been logging it.
  };

  if (port === false) {

    // this has never happened...
  };

  // So now route the WebSocket to the same port
  // as the regular requests are getting.
  svr.proxy.proxyWebSocketRequest(req, socket, head, {
    host: 'localhost',
    port: port
  });

});
Клиентская сторона / Феномены

Разъем подключается так:

var socket = io.connect('http://whatever:8888');

Примерно через 10 секунд после входа в систему я получаю эту ошибку обратно на этот приемник, который нене очень помогает.

socket.on('error', function (data) {
  // this is what gets triggered. ->
  // Firefox can't establish a connection to the server at ws://whatever:8888/socket.io/1/websocket/Nnx08nYaZkLY2N479KX0.
});

GET-запрос Socket.IO, который отправляет браузер, никогда не возвращается - он просто висит в ожидании, даже после того, как ошибка возвращается, поэтому выглядит как ошибка тайм-аута. Сервер никогда не отвечает.

Серверная сторона - работник

Вот как работник получает запрос сокета. Довольно просто Все работники имеют одинаковый код, так что вы думаете, что один из них получит запрос и подтвердит его ...

app.sio.socketio.sockets.on('connection', function (socket) {
  // works... some of the time! all of my workers run this
  // exact same process.
});
Резюме

Тот's много данных, и я сомневаюсь, что кто-то готов противостоять этому, но яя полностью в тупик, нене знаю, где проверить дальше, войти дальше, что угодно, чтобы решить это. Я'Я перепробовал все, что знаю, чтобы понять, в чем проблема, но безрезультатно.

ОБНОВИТЬ

Хорошо, я вполне уверен, что проблема в этом утверждении одомашняя страница github-узла-http-proxy:

узел-http-прокси <= 0.8.x совместимо, если выищем>= 0.10 совместимая версия, пожалуйста, проверьте Caronte

Я использую Node.js v0.10.13, и это то же самое, что некоторые прокомментировали в github-проблемах на эту тему: он просто случайно разрывает соединения с веб-сокетами.

Я пытался реализовать Caronte, 'новее' разветвления, но это совсем не задокументировано, и я изо всех сил старался собрать их документы в работоспособное решение, но я могуЯ получаю переадресацию websockets, мой Socket.IO понижается до опроса.

Есть ли другие идеи о том, как это реализовать и работать? node-http-proxy имеет 8200 загрузок вчера! Конечно, кто-то использует сборку Node с этого года и использует прокси-серверы ....

Что я ищу именно

Я хочу создать прокси-сервер (предпочтительно Node), который проксирует нескольким работникам node.js и который направляет запросы через липкие сессии на основе куки-файла браузера. Этот прокси должен стабильно поддерживать как традиционные запросы, так и веб-сокеты.

Или же...

Я неНе забудьте выполнить вышесказанное с помощью работников кластерных узлов, если это работает. Мое единственное реальное требование - поддерживать липкие сессии на основе куки в заголовке запроса.

Если есть лучший способ выполнить вышесказанное, чем то, что я пытаюсь, я за это.

Ответы на вопрос(3)

Ваш ответ на вопрос