延迟服务总线队列中的消息被处理直到NodeJS的预定时间

时间:2016-04-01 17:36:53

标签: javascript node.js azure

到目前为止,我已经尝试了许多不同的教程来实现这一点,但到目前为止我还没有实现这一目标。

目前我有一个nodejs应用程序,它将消息发送到服务总线队列和另一个持续轮询的nodejs。我的目标是使用特定的时间和日期向队列发送消息,轮询系统可以在该时间和日期处理消息。

到目前为止,我的结果是,只要我发送消息,它就会变得可见并立即处理,这就是我所拥有的

//made some changes after the first suggestion, but still does not work
//what I'm doing here is offsetting the time difference with UTC(im in GMT-7 tz) by adding it manually 
//(this is just a test so if this would have worked I would have made it more elegant)
var scheduled_time = new Date().valueOf() + ((60000*60)*7.5);
  var current_time = Date.now();
  console.log(scheduled_time, current_time);

  var message = {
    body: 'Time ' + current_time.toString(),
    brokerProperties:{
      ScheduledEnqueueTimeUtc: scheduled_time,
      TimeToLive: 8
    },
    customProperties: {
      testproperty: 'TestValue'
    }};

  serviceBus.sendQueueMessage('myqueue', message, function(error){
    if(!error){
      // message sent
      console.log('message sent');
    }
  });

我的接收器非常简单

function receiveMessages() {
  serviceBus.receiveQueueMessage(queue,
      function (error, message) {
        if (error) {
          console.log(error);
        } else {
          console.log('Process after ' + message.brokerProperties.ScheduledEnqueueTimeUtc);
        }
      });
};

到目前为止,我已经阅读了GitHub页面,其中包含了消息属性的描述,这似乎对我所拥有的内容是正确的,但它仍然不起作用。

谢谢

4 个答案:

答案 0 :(得分:3)

Date.now()会在您的时区中返回一个日期,而不是UTC。您需要将其转换为UTC。 This question可以帮助您。

答案 1 :(得分:1)

问题之一似乎是ScheduledEnqueueTimeUtc的格式。我能够使用moment.js从Node.js成功延迟Azure Service Bus中的队列消息,以调整和格式化日期:

// Delay message by 1 hour
var scheduled_time = moment().utc().add(1, 'hour').format('M/D/YYYY H:mm:ss A');
var message = {
    body: 'Time ' + Date.now().toString(),
    brokerProperties: {
        ScheduledEnqueueTimeUtc: scheduled_time
    },
    customProperties: {
        testproperty: 'TestValue'
    }
};

不幸的是,服务总线文档和JavaScript SDK似乎没有提及ScheduledEnqueueTimeUtc应该是什么格式,而不是类型是字符串。但是,如果您查看.NET语言中的代码示例,则使用DateTime.toString()传递该值,该默认值为' G'通用日期和时间格式说明符(例如:5/1/2009 9:00:00 AM)。按照这些例子,我们可以使用像moment.js这样的格式复制格式:" M / D / YYYY H:mm:ss A "。正如TheDude所提到的,请记住必须是UTC 而不是当地时间。

此外,您的TimeToLive值为8可能太短而无法进行处理,请注意使用ScheduledEnqueueTimeUtc 延迟或安排排队并不保证会对其进行处理在指定的日期和时间。它只保证不会事先处理消息。请参阅https://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.scheduledenqueuetimeutc.aspx

中的备注

答案 2 :(得分:0)

根据我的经验,我认为您可以尝试检查Azure上的服务总线和Node.js应用程序的区域,以保留相同的区域。

更多信息,请参阅BrokeredMessage班级https://msdn.microsoft.com/en-us/library/azure/microsoft.servicebus.messaging.brokeredmessage.aspx的经纪人媒体资源。

答案 3 :(得分:0)

上面的示例使用azure-sb程序包,而该程序包又使用HTTP与Azure Service Bus进行通信。较新的@azure/service-bus软件包使用AMQP,并且比azure-sb更具性能。

如果使用@azure/service-bus包,则可以直接在邮件上设置scheduledenqueuetimeutc并将其发送。此属性的类型为Date