我目前有一个使用C++的uWebSockets网络套接字服务器。我想使用Redis进行水平缩放。这意味着我将使用这个Redis客户端。但是,我在酒吧/分频道的实现方面遇到了一个问题。事实上,由于Redis频道订阅需要自己的事件循环(根据这个例子),而且对于uWebSockets应用程序(参见这个例子)显然也是如此,所以我最终会有两个事件循环。我的问题是,我不知道如何正确地运行这两个循环。
我试着在两个不同的线程上运行它们,如果它们完全独立。但是,由于我想向所有web套接字客户端广播即将到来的Redis消息,我需要红宝石线程中的uWebSockets应用实例(参见这个例子)来广播它:
Subscriber sub = redis->subscriber();
sub.on_message([](std::string channel, std::string msg){
app->publish("broadcast", msg, (uWS::OpCode)1);
});因此,这两个事件循环并不是相互独立的,当我收到来自Redis的消息时,需要大约5秒才能被uWebSockets应用程序处理。
有人知道如何正确设置这个Redis /sub功能吗?谢谢你的帮助。
发布于 2022-04-17 13:44:16
我设法解决了我的问题。
我发现在第二个线程中调用app->publish(...)并不是线程安全的。事实上,一个有趣的帖子告诉我,为了从另一个线程访问应用程序,我们必须在事件循环中使用defer方法。因此,结构变成:
...
uWS::SSLApp *app = nullptr;
uWS::Loop *loop = nullptr;
Redis *redis = nullptr;
...
void redisEventLoopThread(Subscriber *sub) {
sub->on_message([](string channel, string msg) {
loop->defer([msg]() {
app->publish(channel, msg, ...);
});
});
sub->subscribe("channel_name");
while (true) {
try {
sub->consume();
} catch (const Error &err) {...}
}
}
...
int main() {
app = new uWS::SSLApp();
loop = uWS::Loop::get();
redis = new Redis(...);
Subscriber sub = redis->subscriber();
thread redisThread(redisEventLoopThread, &sub);
app->ws<...>(...).listen(...).run();
...
}https://stackoverflow.com/questions/71896776
复制相似问题