检索已发布的消息而不路由 elsewhere/after 在 Angular 中发送消息

Retrieve published message without routing elsewhere/after sending message in Angular

我在 angular 中实现了 PubNub,我可以发送和接收消息。 但我面临以下挑战。

发送消息后,在fetchMessage方法中收不到消息。我必须路由到其他地方。 我尝试添加一个监听器并订阅了一个频道,但它没有按预期工作。

下面是我实现的代码片段:

// publish new message

this.pubnub.publish(
      {
        channel: this.currentRoom, // Channel Name
        message: {
          body: this.message ? this.message : null,
          sender: this.sender,
          reciever: this.reciever,
          id: this.currentUserId
        },
        storeInHistory: true,
      },
      function (status, response) {
        if (status.error) {
          console.log(status);
        }
      }
    );

// fetch message method

    this.pubnub.fetchMessages(
      {
        channels: [this.currentRoom],
        count: 100
      },
      (status, response) => {
        // handle response
        console.log(response);
      }
    );

谢谢你:)

在这种情况下,您尝试使用历史记录来获取消息而不是添加侦听器并订阅频道是否有任何特殊原因?大多数时候,您的 PubNub 逻辑应该类似于:

    // setup a listener for new messages and subscribe

    this.pubnub.addListener({
      message: function(message) {
        console.log(message);
      }
    });
    
    this.pubnub.subscribe({
      channels: [this.currentRoom] 
    });
    
    
    // publish new message

    this.pubnub.publish(
      {
        channel: this.currentRoom, // Channel Name
        message: {
          body: this.message ? this.message : null,
          sender: this.sender,
          reciever: this.reciever,
          id: this.currentUserId
        },
        storeInHistory: true,
      },
      function (status, response) {
        if (status.error) {
          console.log(status);
        }
      }
    );

fetchMessages 没有返回您新添加的消息的原因是它需要一些时间才能在存储服务器上传播。对于您的代码片段,历史记录调用甚至在消息真正发布之前就已发生,您可以通过在 publish 回调中记录响应来观察这一点。一般来说,如果您想立即访问新消息,应该使用 addListener/subscribe 组合,fetchMessages 主要用于与批处理操作相关的用例。

请尝试在确认消息已发送的块中获取新消息,看看它是否有效。

分布式系统最终一致性

@salet 上面的回答触及了分布式系统和存储的真正挑战。 @salet 说

...newly added message is that it takes some time to propagate it on the storage servers...

这是分布式持久系统的最终一致性挑战。虽然 pub/sub 是实时的(< 1/4s),但消息的存储是“接近实时”的,因为它最多可能需要一秒钟才能传播到存储服务器。

我会问,“你想做什么?”。这只是一个“消息是否持续存在”测试,还是您打算在您的应用程序中实现它。如果是前者,请参见下文,但如果是后者,请不要那样做。

如果您只是想证明消息已存储,可以在获取消息之前在 message 回调中放置一个“延迟”(setTimeout),但不要这样做一个生产应用程序,因为它不可靠,也不是最佳实践。

this.pubnub.addListener({
  message: function(message) {
    console.log(message);

    setTimeout(
      function(){ 
        this.pubnub.fetchMessages(
          {
            channels: [this.currentRoom],
            count: 1 // just get the last message
          },
          (status, response) => {
            console.log(status, response);
          }
        );
      },
      2000
    );
  }
});

this.pubnub.subscribe({
  channels: [this.currentRoom] 
});

this.pubnub.publish(
  {
    channel: this.currentRoom,
    message: {
      body: this.message ? this.message : null,
      sender: this.sender,
      reciever: this.reciever,
      id: this.currentUserId
    },
    storeInHistory: true,
  },
  function (status, response) {
    if (status.error) {
      console.log(status);
    }
  }
);

我再说一遍,这不是最佳实践代码,它只是“证明最后发布的消息(以及该订阅者收到的消息)被保留”。如果在消息的存储中有任何额外的延迟,它仍然可能找不到消息,但在 2 秒后就不太可能了。或者您可能一次收到多条消息,而 count: 1 将无法正常工作,但同样,这是为了一个简单的测试,其中发布消息(和接收消息)的速度“很慢”。

如果您还有其他问题,建议您联系 PubNub Support