草庐IT

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

coder 2023-07-19 原文

我正在尝试制作 this打包工作。

redis版本:stable 4.0.6

我是这样连接Redis的,没有问题。

发布订阅.js

var redis = require("redis");
var psRedis = redis.createClient();

psRedis.auth("mypasswordishere", function (callback) {
  console.log("connected");
});

module.exports.psRedis = psRedis;

启动Node.js应用程序后,我可以在控制台上看到“已连接”并执行操作,我已经检查过了。

我的 test.js 文件在下面。

测试.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;

但是,当我访问 /pubsubTest 时,只有消息 id 出现在控制台上。

Message sent. ID: exb289xu0i7IaQPEy1wA4O7xQQ6n0CAp

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

{ id: 'exb289xu0i7IaQPEy1wA4O7xQQ6n0CAp',
  message: 'Hello World 1',
  rc: 1,
  fr: 1515802884138,
  sent: 1515802880098 }

谢谢。

最佳答案

receiveMessage 不会“触发”。您需要在发送消息后调用它。 您正在寻找的是 rsmq 提供的实时选项。

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

现在,对于通过sendMessage 添加到队列的每条新消息,PUBLISH 消息将发送到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,它会为您提供一个message 事件,您可以使用 收听该事件>.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 会为您处理这些事情,您也可以提供自己的轮询间隔

关于Node.js rsmq - 在重新启动 Node.js 应用程序之前,新消息不会变得可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48235491/

有关Node.js rsmq - 在重新启动 Node.js 应用程序之前,新消息不会变得可见的更多相关文章

  1. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  5. ruby - 即时确定方法的可见性 - 2

    我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust

  6. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  7. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  8. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

  9. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  10. ruby-on-rails - 在 Flash 警报 Rails 3 中显示错误消息 - 2

    如果我在模型中设置验证消息validates:name,:presence=>{:message=>'Thenamecantbeblank.'}我如何让该消息显示在闪光警报中,这是我迄今为止尝试过的方法defcreate@message=Message.new(params[:message])if@message.valid?ContactMailer.send_mail(@message).deliverredirect_to(root_path,:notice=>"Thanksforyourmessage,Iwillbeintouchsoon")elseflash[:error]

随机推荐