Например, socket.io иногда не подключается на стороне клиента при использовании обратного прокси

Используя node-http-proxy, я настроил обратный прокси для запросов маршрутизации:

var httpProxy = require('http-proxy');
var server = httpProxy.createServer({
    hostnameOnly: true,
    router: {
        'www.example.com': 'localhost:3002'
    }
}).listen(80);

Теперь, когда я запускаю первый пример на http://socket.io/, сокет иногда не соединяется с клиентом. Я создал два файла для проверки этого: server.js и index.html. Чтобы запустить приложение узла, я запускаю server.js.

server.js:

var app = require('http').createServer(handler)
    , io = require('socket.io').listen(app)
    , fs = require('fs')

app.listen(3002);

function handler (req, res) {
    fs.readFile(__dirname + '/index.html',
    function (err, data) {
        if (err) {
            res.writeHead(500);
            return res.end('Error loading index.html');
        }

        res.writeHead(200);
        res.end(data);
    });
}

io.sockets.on('connection', function (socket) {
    console.log("Socket connected");
});

index.html:

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect();
    setInterval(function() {
        console.log(socket.socket.connected);
    }, 1000)
</script>

Когда клиент не соединяется, после того, как сокет соединяется с сервером, я повторно получаю следующий вывод с интервалами +/- 10 секунд:

debug - setting request GET /socket.io/1/xhr-polling/Cqcw5xUjQ-B-Hw3FGF7Y?t=1385128607702
debug - setting poll timeout
debug - discarding transport
debug - cleared heartbeat interval for client Cqcw5xUjQ-B-Hw3FGF7Y

Теперь, когда я обновляю браузер несколько раз, сокет всегда соединяется с сервером (т. Е. Он всегда регистрирует "Соединение с сокетом "), но иногда он не подключается на стороне клиента:console.log(socket.socket.connected) иногда повторно печатает "ложь" после обновления index.html, а после обновления другой страницы может многократно печатать "истину" или "ложь" снова, если сокет не подключался или не подключался к клиенту.

Этот пример работает на стороне клиента, когда я не использую обратный прокси-сервер, поэтому, когда я запускаю server.js на порту 80 на www.example.com. Было бы замечательно, если бы кто-то мог указать мне, что может быть причиной этой проблемы. Я использую node.js v0.8.23, socket.io версии 0.9.14 и node-http-proxy версию 0.10.1.

ОБНОВИТЬ

Вероятно, я на самом деле использую узел v0.10.21. Я думал, что я использовал v0.8.23, переключая версию узла с помощью nvm, но по какой-то причине он продолжает переключаться обратно на v0.10. Известно, что http-proxy не поддерживает веб-сокеты для версий узлов более поздних, чем 0.8, поэтому это может быть причиной. Я использую решение Робертклепа, пока не найду что-то лучшее.

2 ответа

Решение

Это действительно была версия узла, которую я использовал. Node-http-proxy не работает для версии узла>0.8 (см. HTTP-прокси Node с proxytable и websockets). Я думал, что я использовал v0.8.23, но на самом деле я использовал v0.10.21. Используя n, я мог бы заставить узел работать на v0.8.23 наверняка, и теперь он, кажется, работает. Я настоятельно рекомендую для сброса версии узла.

Я думаю, что проблема может быть в том, что socket.io Первоначально пытается использовать WebSockets в качестве транспортного средства, и когда это не работает (я не знаю, если node-http-proxy может прокси-соединения WS), он возвращается к транспорту, который работает (xhr-polling) но клиент и / или сервер запутываются в процессе.

Попробуйте отключить websocket а также flashsocket Транспорт, чтобы увидеть, если это делает его более надежным:

io.set('transports', [ 'xhr-polling', 'jsonp-polling', 'htmlfile' ]);

( больше информации)

Другие вопросы по тегам