Redis长轮询Pub / Sub频繁的消息阻止

时间:2013-07-28 23:27:15

标签: nginx lua redis

我正试图绕过Redis Pub / Sub API并设置一个长轮询服务器。

此lua脚本订阅“测试”频道并返回收到的新消息:

nginx.conf:

location /poll {
  lua_need_request_body on;
  default_type 'text/plain';
  content_by_lua_file '/usr/local/nginx/html/poll.lua';
}

poll.lua:

local redis = require "redis";
local red = redis:new();
local cjson = require "cjson";

red:set_timeout(30000) -- 30 sec

local resCon, err = red:connect("127.0.0.1", 6379)
if not resCon then
  ngx.print("error")
  return
end

local resSub, err = red:subscribe('r:' .. ngx.var["arg_r"]:gsub('%W',''))

if not resSub then
  ngx.print("error")
  return
end

if resSub == ngx.null then
  ngx.print("error")
  return
end

local resMsg, err = red:read_reply()

if not resMsg then
  ngx.say("0")
  return
end

ngx.say(cjson.encode(resMsg))

client.js:

var tmpR = 'test';

function poll() {
  $.get('/poll', {'r':tmpR}, function(data){
    if (data !== "error") {
      console.log(data);
      window.setTimeout(function(){
        poll();
      },1000);
    } else {
      console.log('poll fail');
    }
  })
}

现在,如果我从redis-cli发送publish r:test hello,我会在客户端收到消息,服务器会使用1响应redis-cli。但是,如果我快速发送两条消息,则第二条消息不会广播,服务器会以0响应。

我的频道是否每秒只能接收一条消息,或者,这是否是用户可以向频道广播的消息频率的限制?

这是否是在nginx上接近此轮询服务器的正确方法,假设一次可以连接多个用户?在计时器上使用GET请求会更有效吗?

1 个答案:

答案 0 :(得分:1)

给定两个连续的消息,只有一个消息会让订阅者听取结果。发送第二条消息时,没有订阅者正在侦听。唯一的订户正在处理先前的结果并将其返回给用户。

Redis 维护消息队列或类似消息,以确保先前侦听的客户端在重新连接时将收到丢失的消息。