我打算使用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
我按照以下步骤测试了它:
现在,“发送:blablah”打印在控制台上,res.end(reply)
已经执行,但客户端什么也没收到。我多次重复步骤3,然后按预期工作。如果我重新启动客户端,则无法再接收前几个响应。
我该如何解决这个问题?
答案 0 :(得分:1)
我认为这里可能发生的事情是你在等待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;
});
}