Node.js Google PubSub订阅服务器未收到某些消息

时间:2020-04-19 17:34:57

标签: node.js google-cloud-platform socket.io publish-subscribe google-cloud-pubsub

摘要:

我的Node.js应用程序中具有聊天功能,并且希望通过socket.io向客户端发送消息。我通过PubSub触发向客户端的发射。现在,在运行PubSub Subscription时,在大约70%的情况下一切正常(即打印出消息),但有时会停止并且不执行任何操作(特别是不会打印出错误)。 我可以确认丢失的30%(消息)已发布到该主题,因为同一主题的其他订阅会收到消息。

任何有关调试的帮助将不胜感激。

详细信息

这是我的堆栈:

  • Node.js
  • socket.io
  • express.js
  • passport.js
  • MongoDB
  • react.js

过程:

  • Anna 在聊天中发送一条消息(这既写入数据库,也发布到PubSub主题“消息”)
  • Node.js Express应用运行一个订阅,然后根据消息内容向其他应接收该消息的人发出。
  • 在这种情况下,与Anna处于同一频道的
  • BoB 会收到消息。

为什么我不直接从安娜发给鲍勃?原因是我想在消息之间使用一个AppEngine并可能在其中添加一些逻辑,这似乎是一个好方法。

订阅

const pubSubClient = require('./client');

const errorHandler = function(error) {
    console.error(`ERROR: ${error}`);
    throw error;
};

module.exports = listenForMessages =(subscriptionName="messageReceiver",io) => {
    const subscription = pubSubClient.subscription(subscriptionName);

    // Listen for new messages until timeout is hit
    subscription.on("message", (message) => {
        console.log(`Received message ${message.id}:`);
        const parsedMessage = JSON.parse(message.data)
        parsedMessage._id = message.id
        console.log(parsedMessage)

        if (parsedMessage.to === "admin") {
            io.to(`admin:${parsedMessage.from}`).emit("NewMessage", parsedMessage);
        } else {
            io.to(`${parsedMessage.to}`).emit("NewMessage", parsedMessage);
        }
        message.ack();
    });

    subscription.on('error', errorHandler);
}

Server.js

...
const listenForMessages = require("./message_processing/listen");
listenForMessages("messageReceiver", io);

示例控制台输出

以下控制台输出是通过使用两个彼此聊天的浏览器在本地运行该应用程序(隐身地运行)生成的。可以看出,只有最后一条消息实际上是由侦听器接收的(并打印出来)。有趣的是,由于呼叫的异步性质,接收到的消息的打印输出在发送消息的日志之前出现(即,在这里延迟肯定不是问题)。

[0] went into deserialize user
[0] Message 875007020424601 published.
[0] went into deserialize user
[0] Message 875006704834317 published.
[0] went into deserialize user
[0] Message 875006583857400 published.
[0] went into deserialize user
[0] Message 875006520104287 published.
[0] went into deserialize user
[0] Message 875006699141463 published.
[0] went into deserialize user
[0] Received message 875006881073134:
[0] {
[0]   from: '5e949f73aeed81beefaf6daa',
[0]   to: 'admin',
[0]   content: 'i6',
[0]   seenByUser: true,
[0]   type: 'message',
[0]   createdByUser: true,
[0]   createdAt: '2020-04-20T07:44:54.280Z',
[0]   _id: '875006881073134'
[0] }
[0] Message 875006881073134 published.

在其他情况下,较早的消息起作用,然后侦听器似乎停止了。

1 个答案:

答案 0 :(得分:1)

您可以通过几件事来检查正在发生的事情:

  1. 转到topic page,选择主题以查看详细信息,然后查看发布率。确保就发布/订阅而言,您认为正在发布的消息实际上已成功发布。如果发布失败,则有可能将它们传递给您的一个订阅者,而不是另一个。
  2. 转到subscription page,选择订阅以查看详细信息,然后查看“未确认的邮件计数”和“最早的未确认的邮件年龄”图。如果这些非零值,则意味着有些消息没有传递到您的订户。如果它们为零,则意味着消息将传递到您的订户并得到您的确认。

如果未确认的消息数为零,则可能的原因是流氓进程充当接收消息的订阅上的订阅者。也许您的服务的先前实例仍在意外运行?或者可能应该使用其他订阅的另一个任务正在使用同一订阅。

要注意的另一件事是,订阅者将仅收到有关在发布消息之前创建的订阅的消息。因此,如果您启动了发布者并发布了一些消息,然后创建了订阅,例如在订阅者启动时,那么订阅者将不会收到这些较早的消息。