简体   繁体   English

Node.js Google PubSub 订阅者未收到某些消息

[英]Node.js Google PubSub Subscriber does not receive SOME messages

Summary:概括:

I have a chat functionality in my Node.js app and want to send messages to the clients via socket.io.我的Node.js应用程序中有一个聊天功能,并希望通过 socket.io 向客户端发送消息。 I trigger the emit to the client via PubSub.我通过 PubSub 触发向客户端发送。 Now, when running the PubSub Subscription everything works (ie prints out messages) in roughly 70% of the cases, but would sometimes just stop and not do anything (in particular it would also not print out an error).现在,当运行 PubSub Subscription 时,大约 70% 的情况下一切正常(即打印出消息),但有时会停止而不做任何事情(特别是它也不会打印出错误)。 I can confirm that the missing 30% (messages) are being published to the topic though, as a different subscription to the same topic receives the messages.我可以确认丢失的 30%(消息)正在发布到主题,因为对同一主题的不同订阅会收到消息。

Any help with debugging this would be highly appreciated.任何有关调试的帮助将不胜感激。

Details细节

This is my Stack:这是我的堆栈:

  • Node.js Node.js
  • socket.io socket.io
  • express.js express.js
  • passport.js护照.js
  • MongoDB MongoDB
  • react.js反应.js

Process:过程:

  • Anna sends a message in chat (this writes to the database and also publishes to PubSub topic "messages") Anna在聊天中发送消息(这会写入数据库并发布到 PubSub 主题“消息”)
  • Node.js express app runs a subscription and would then based on the message content emit to whoever else should receive the message. Node.js express 应用程序运行订阅,然后根据消息内容发送给其他应该接收消息的人。
  • BoB who is on the same channel as Anna would, in this case, receive the message.在这种情况下,与 Anna 在同一频道上的BoB会收到消息。

Why do I not directly emit from Anna to Bob?为什么我不直接从 Anna 发射到 Bob? The reason being that I want to have an AppEngine in between the messages and potentially add some logic there, this seemed a good way doing it.原因是我想在消息之间有一个 AppEngine 并可能在那里添加一些逻辑,这似乎是一个好方法。

Subscription订阅

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服务器.js

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

Sample console output样品台 output

The following console output was generated by running the app locally with two browsers [one in incognito] chatting with each other.以下控制台 output 是通过在本地运行应用程序并使用两个浏览器 [一个隐身] 相互聊天生成的。 It can be seen that only the very last message was actually picked up by the listener (and printed out).可以看出,只有最后一条消息实际上被侦听器拾取(并打印出来)。 Funnily enough, due to the async nature of the calls, the printout of the received message came before the log that the message was sent (ie latency surely can't be a problem here).有趣的是,由于调用的异步特性,接收到的消息的打印输出出现在消息发送的日志之前(即延迟肯定不会成为问题)。

[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.

In some other cases, earlier messages work and then the listener seems to stop.在其他一些情况下,较早的消息起作用,然后侦听器似乎停止了。

There are a couple of things you could do to check what is happening:您可以做几件事来检查正在发生的事情:

  1. Go to the topic page , select the topic to see the details, and look at the publish rate. Go 到主题页,select 主题看详情,看发布率。 Ensure that the messages you think are being published are actually being published successfully as far as Pub/Sub is concerned.确保就 Pub/Sub 而言,您认为正在发布的消息实际上已成功发布。 If publishes are failing, it is possible they could be delivered to one of your subscribers and not the other.如果发布失败,它们可能会交付给您的一个订阅者,而不是另一个。
  2. Go to the subscription page , select the subscription to see the details, and look at the "Unacked message count" and "Oldest unacked message age" graphs. Go 到 订阅页面,select 订阅查看详情,并查看“Unacked message count”和“Oldest unacked message age”图表。 If these are nonzero, then that means there are messages not getting delivered to your subscriber.如果这些不为零,则意味着有消息未传递给您的订阅者。 If they are zero, then that means the messages are getting delivered to and acknowledged by your subscriber.如果它们为零,则意味着消息正在传递给您的订阅者并得到您的订阅者的确认。

If the number of unacked messages is zero, then the likely cause is a rogue processes acting as a subscriber on the subscription receiving the messages.如果未确认消息的数量为零,则可能的原因是在接收消息的订阅上充当订阅者的流氓进程。 Perhaps a previous instance of your service is still running unexpectedly?也许您的服务的先前实例仍在意外运行? Or possibly another task that should use a different subscription is using the same subscription.或者可能另一个应该使用不同订阅的任务正在使用相同的订阅。

Another thing to be aware of is that subscribers will only receive messages on subscriptions that were created before messages were published.要注意的另一件事是,订阅者只会收到在消息发布之前创建的订阅的消息。 Therefore, if you started up the publisher and published some messages and then created the subscription, say at the time when the subscriber was started up, then the subscriber will not receive those earlier messages.因此,如果您启动了发布者并发布了一些消息,然后创建了订阅,例如在订阅者启动时,那么订阅者将不会收到那些较早的消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM