Почему я не смог получить первые несколько ответов от httpJerver узла JS? - PullRequest
0 голосов
/ 13 апреля 2011

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

Вот код на стороне сервера (server.js):

var util = require('util');
var redis = require('redis').createClient(6379, '192.168.1.254');
var http = require('http');
redis.on("error", function (err) {
    console.log("Error " + err);
});

var server = http.createServer(requestListener);
server.listen(9898, '192.168.1.254');

function requestListener(req, res) {
        util.log('Connected.');
        redis.brpoplpush('msg:q:1', 'msg:s:1', 20, function(err, reply) {
                if (err) {
                        util.log('ERROR: ' + err);
                }
                var length = reply ? reply.length : 0;
                res.writeHead(200, {
                        'Content-Type':'text/plain',
                        'Content-Length':length
                });
                if (length) {
                        res.end(reply);
                        util.log('Sent: ' + reply);
                } else {
                        res.end('');
                }
        });
}

И код клиента (client.sh):

#!/bin/bash
while [ 1 ]
do
        curl -i http://192.168.1.254:9898
done

Я проверил следующие шаги:

  1. узел server.js
  2. . / Client.sh
  3. В Redis, LPUSH ('msg: q: 1', 'blablah')

Теперь, "Отправлено: блабла" напечатано на консоли, res.end(reply) извинено, но клиент ничего не получает. Я повторяю шаг 3 много раз, затем он работает, как и ожидалось. Если я перезапущу клиент, первые несколько ответов не будут получены снова.

Как я могу решить эту проблему?

1 Ответ

1 голос
/ 20 сентября 2011

Я думаю, что здесь может произойти, вы прервали завиток, пока он ждал ответа от redis.После отмены HTTP-клиента команда redis остается активной.Затем вы помещаете другой элемент в очередь, команда redis возвращается, но не имеет ответа HTTP, чтобы записать его.Когда вы снова запустите цикл curl, вы обнаружите, что очередь пуста.

Вот модифицированная версия вашей программы, которая передает ответ и обнаруживает прерывание клиента.Он не помещает элемент обратно в очередь, но вы также можете сделать это.

var util = require('util');
var redis = require('redis').createClient();
var http = require('http');

redis.on("error", function (err) {
    console.log("Redis error " + err);
});
redis.on("ready", function () {
    console.log("Redis client ready");
});

var server = http.createServer(requestListener);
server.listen(9898);

function requestListener(req, res) {
    var aborted = false;

    res.writeHead(200, {
        "Content-Type": "text/plain"
    });
    res.write("Checking redis...\n");
    redis.brpoplpush('q', 's', 20, function (err, reply) {
        if (aborted) {
            return console.log("Client aborted before redis reply came back.");
        }

        if (err) {
            return res.end("Redis error");
        }

        res.end("Redis reply: " + reply);
    });
    req.on("aborted", function () {
        console.log("HTTP client aborted.");
        aborted = true;
    });
}
...