Резюме:
В моем приложении Node.js
есть функция чата, и я хочу отправлять сообщения клиентам через socket.io. Я запускаю emit для клиента через PubSub. Теперь, при запуске подписки PubSub все работает (то есть печатает сообщения) примерно в 70% случаев, но иногда просто останавливается и ничего не делает (в частности, это также не выводит ошибку). Я могу подтвердить, что недостающие 30% (сообщения) публикуются в topi c, хотя, поскольку другая подписка на тот же topi c получает сообщения.
Любая помощь с отладкой это будет высоко ценится
Подробности
Это мой стек:
- Node.js
- socket.io
- express. js
- паспорт. js
- MongoDB
- реакция. js
Процесс:
- Анна отправляет сообщение в чате (пишет в базу данных, а также публикует в PubSub topi c "messages")
- Node.js express app запускает подписку и затем на основе содержимого сообщения отправляет сообщение тому, кто еще должен получить сообщение.
- BoB , который находится на том же канале, что и Анна, в этом случае получит сообщение.
Почему я не посылаю напрямую от Анны Бобу? Причина в том, что я хочу иметь AppEngine между сообщениями и потенциально добавлять туда логи c, это казалось хорошим способом сделать это.
Подписка
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);
}
Сервер. js
...
const listenForMessages = require("./message_processing/listen");
listenForMessages("messageReceiver", io);
Пример вывода на консоль
Следующий вывод на консоль был получен при локальном запуске приложения с двумя браузерами [один в режиме инкогнито], общающимися друг с другом. Видно, что только последнее сообщение было фактически получено слушателем (и распечатано). Как ни странно, из-за асинхронной природы вызовов c распечатка полученного сообщения пришла до того, как журнал был отправлен (то есть задержка, конечно, не может быть проблемой здесь).
[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.
В некоторых других случаях более ранние сообщения работают, а затем слушатель, кажется, останавливается.