开发者

Why I couldn't get first few responses from nodeJS' httpServer?

开发者 https://www.devze.com 2023-02-25 11:51 出处:网络
I\'m planning to use nodeJS as my comet server and I wrote some code for testing, but there is an issue that when client connected to the server for the first time, it couldn\'t get response from serv

I'm planning to use nodeJS as my comet server and I wrote some code for testing, but there is an issue that when client connected to the server for the first time, it couldn't get response from server.

Here is the server-side code (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('');
                }
        });
}

And the client code (client.sh):

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

I tested it following steps:

  1. node server.js
  2. ./client.sh
  3. In redis, LPUSH('msg:q:1', 'blablah')

Now, "Sent: blablah" printed on console, res.end(reply) excuted, but client receives nothing. I repeat step 3 for many times, then it works as expect. If I restart the client, the first few responses can't be received again.

How can I resolve this?


I think what might happening here is you've aborted curl while it was waiting for the response from redis. After the HTTP client is aborted, the redis command still stays active. You then push another element onto the queue, the redis command returns, but has no HTTP response to write it to. When you start the curl loop again, you find the queue empty.

Here's a modified version of your program that streams the response and detects a client abort. It doesn't put the element back on the queue, but you could certainly do that as well.

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;
    });
}
0

精彩评论

暂无评论...
验证码 换一张
取 消