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 и который направляет запросы через липкие сессии на основе куки-файла браузера. Этот прокси должен стабильно поддерживать как традиционные запросы, так и веб-сокеты.
Или же...Я неНе забудьте выполнить вышесказанное с помощью работников кластерных узлов, если это работает. Мое единственное реальное требование - поддерживать липкие сессии на основе куки в заголовке запроса.
Если есть лучший способ выполнить вышесказанное, чем то, что я пытаюсь, я за это.