Node.js rsmq - 重新启动Node.js应用程序之前,新消息不可见

时间:2018-01-12 23:39:08

标签: node.js redis node-redis

我试图让this包工作。

redis版本:稳定4.0.6

我像这样连接Redis,那里没有问题。

pubsub.js

   var viz = svg.selectAll("path")
              .data(data)
              .enter()
              .append("path")
              .attr({
                d: function(d) {
                  return lineFun(d.arr)
                },
                "stroke": "purple",
                "stroke-width": 2,
                "fill": "none",
                "class":"line"
              })
              .style("stroke",function(){
                  return d.color=color(d.arr);
              })
              .attr("transform", "translate(48, " + 10 +")")
              ;    




}

      d3.json("sample-data.json",function(error,data){

                //check the file loaded properly
                if (error) {  //is there an error?
                    console.log(error);  //if so, log it to the console
                } else {      //If not we're golden!
                      //Now show me the money!
                    ds=data; //put the data in the global var
                }
            data.forEach(function(jsonData){
                 var lineData = d3.range(0, jsonData.spend, 100)
                    .map(x => [x, (jsonData.alpha * (1 - Math.pow(2.71828, (-jsonData.beta * x))))] );
                       /*  console.log("this is the data:",lineData);*/
                    //i think line date returns an array with each item in it also an array of 2 items
                    var arr = [];
                    for (var i = 0; i < lineData.length; i++) {
                        arr.push({
                           x: lineData[i][0],  
                           y: lineData[i][1]
                        });
                    }
                    jsonData.arr = arr;
                   console.log(jsonData);
            });

           buildLine(data);
      });

启动Node.js应用程序后,我可以看到&#34; connected&#34;在控制台上并执行操作,我已经检查过了。

我的var redis = require("redis"); var psRedis = redis.createClient(); psRedis.auth("mypasswordishere", function (callback) { console.log("connected"); }); module.exports.psRedis = psRedis; 文件位于下方。

test.js

test.js

但是,当我访问var express = require('express'); var router = express.Router(); var path = require("path"); var bodyParser = require('body-parser'); var async1 = require("async"); var client = require("../databases/redis/redis.js").client; var RedisSMQ = require("rsmq"); var psRedis = require("./realtime/operations/pubsub").psRedis; var rsmq = new RedisSMQ({client: psRedis}); rsmq.createQueue({qname: "myqueue"}, function (err, resp) { if (resp === 1) { console.log("queue created"); } }); rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) { if (resp) { console.log(resp); } }); router.get('/pubsubTest', function (req, res, next) { async1.waterfall([ function (callback) { rsmq.sendMessage({qname: "myqueue", message: "Hello World 1"}, function (err, resp) { if (resp) { console.log("Message sent. ID:", resp); } }); callback(null, 'done!'); } ], function (err, result) { res.sendStatus(200); }); }); module.exports = router; 时,控制台上只会显示消息ID。

  

发送消息。 ID:exb289xu0i7IaQPEy1wA4O7xQQ6n0CAp

如果我重新启动我的Node.js应用程序,我会看到下面的结果,这是预期的。为什么不立即出现?

/pubsubTest

谢谢。

1 个答案:

答案 0 :(得分:2)

receiveMessage不会“触发”。您发送邮件后,需要来称呼它。 您正在寻找的是rsmq提供的实时选项。

var rsmq = new RedisSMQ({client: psRedis}, ns: "rsmq",realtime :true});

现在,通过sendMessage添加到队列中的每条新消息中,都会向rsmq:rt:{qname}发送内容为{msg}的发布消息。就您而言,sendMessage将发出一个事件,即rsmq:rt:myqueue

有两种解决方案,都将使用事件rsmq:rt:myqueue

1。第一个将使用redis客户端,该客户端可以使用redis提供的subscribe方法订阅此发布的事件,以实现PUB / SUB。

 var redis = require('redis');
    const subscribe = redis.createClient();
    subscribe.subscribe('rsmq:rt:myqueue');
    subscribe.on('message', function(msg) {     //msg=>'rsmq:rt:myqueue'
        rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) {
            if (resp) {
                console.log(resp);
            }
        });
    });

整个代码如下:

var express = require('express');
var router = express.Router();
var path = require("path");
var bodyParser = require('body-parser');
var async1 = require("async");
var client = require("../databases/redis/redis.js").client;
var psRedis = require("./realtime/operations/pubsub").psRedis;
var rsmq = new RedisSMQ({client: psRedis}, ns: "rsmq",realtime :true});

rsmq.createQueue({qname: "myqueue"}, function (err, resp) {
  if (resp === 1) {
    console.log("queue created");
  }
});

const subscribe = redis.createClient( 6379,"127.0.0.1"); //creating new 
worker and pass your credentials
subscribe.subscribe('rsmq:rt:myqueue');
subscribe.on('message', function(msg) {     //msg=>'rsmq:rt:myqueue'
    rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) {
        if (resp) {
            console.log(resp);
        }
    });
});

router.get('/pubsubTest', function (req, res, next) {
  async1.waterfall([
    function (callback) {
      rsmq.sendMessage({qname: "myqueue", message: "Hello World 1"}, 
function (err, 
      resp) {
        if (resp) {
          console.log("Message sent. ID:", resp);
        }});
      callback(null, 'done!');
    }
  ], function (err, result) {
    res.sendStatus(200);
  });
});
module.exports = router;

2。第二种解决方法是使用rsmq-worker,它将为您提供一个 消息 事件,您可以使用.on方法收听该事件。

var RSMQWorker = require( "rsmq-worker" );
var worker = new RSMQWorker( "myqueue" ,{interval:.1}); // this worker 
will poll the queue every .1 second.

worker.on( "message", function( message, next, msgid ){
     if(message){
         console.log(message);
     }
    next();
 });
worker.start();

整个代码如下:

var express = require('express');
var router = express.Router();
var path = require("path");
var bodyParser = require('body-parser');
var async1 = require("async");
var client = require("../databases/redis/redis.js").client;
var psRedis = require("./realtime/operations/pubsub").psRedis;
var rsmq = new RedisSMQ({client: psRedis},{ ns: "rsmq",realtime :true});

rsmq.createQueue({qname: "myqueue"}, function (err, resp) {
    if (resp === 1) {
        console.log("queue created");
    }
});

var RSMQWorker = require( "rsmq-worker" );
var worker = new RSMQWorker( "myqueue" ,{interval:.1});
worker.on( "message", function( message, next, msgid ){
        if(message){
            console.log(message);
        }
    next();
});


// optional error listeners
worker.on('error', function( err, msg ){
    console.log( "ERROR", err, msg.id );
});
worker.on('exceeded', function( msg ){
console.log( "EXCEEDED", msg.id );
});
worker.on('timeout', function( msg ){
    console.log( "TIMEOUT", msg.id, msg.rc );
});
worker.start();


router.get('/pubsubTest', function (req, res, next) {
    async1.waterfall([
        function (callback) {
            rsmq.sendMessage({qname: "myqueue", message: "Hello World1"}
            ,function (err, resp) {
                if (resp) {
                    console.log("Message sent. ID:", resp);
                }});
        callback(null, 'done!');
        }
    ], function (err, result) {
    res.sendStatus(200);
    });
});
module.exports = router;

注意:在第一个解决方案中,您将需要使用deleteMessage删除从队列中收到的消息,或者也可以使用popMessage来接收最后一条消息并为您删除。如果您不删除该消息,则将再次获得所有消息,直到该特定消息的超时时间结束为止。

由于这个原因,我更喜欢使用第二种解决方案,rsmq会为您处理这些事情,并且您还可以提供自己的轮询间隔