首页 > 解决方案 > 使用带有条件变量的 cpp_redis pub/sub 问题

问题描述

我使用 cpp_redis 创建了两个应用程序;一个使用发布和另一个订阅者。我已将 redis 客户端包装到一个类中,因为我希望将来能够更改通信。我遇到的问题是使用条件变量时我的班级的回调不起作用。使用 redis-cli 监视器,我可以看到正在发布但订阅者应用程序未接收到的事件。如果我将代码更改为使用原子变量并替换主循环中的条件变量并添加while(!atomic_var) 等待;,订阅回调有效。

class EventComms : public IEventComms
{
public:
    EventComms(cpp_redis::client &client, string channel);
    ~EventComms();
    void Publish(string uid);
    void Subscribe(TSubCallbackFunction callback);
private:
    string comms_channel;
    cpp_redis::client &redis_client;
    cpp_redis::subscriber sub;
};

void EventComms::Subscribe(TSubCallbackFunction callback) {
    sub.connect();
    sub.subscribe(comms_channel, 
            [&](const string& channel, const string& message){
        if (comms_channel == channel) {
            callback(message);
        }
    });
    sub.commit();
}

我的发布代码。

int main(int argc, char* argv[]) {
    cpp_redis::client client;
    client.connect();
    EventComms *comms = new EventComms(client, "/TEST");
    char c;
    while (1) {
        cout << "Waiting for commands " << endl;
        c = getchar();
        switch (c) {
            case 'p':
            {
                string uuid = generateUuidString();
                comms->Publish(uuid);
                break;
            }
            default:
            break;
        }
    }
    return 0;
}

我的订阅代码。

int main(int argc, char *argv[]) {
    std::condition_variable cv;
    cpp_redis::client client;
    client.connect();
    EventComms comms(client, "/TEST");
        comms.Subscribe([&](string message) {
        event_id = message;
        cout << "rx message: " << message << endl;
        waitcv.notify_all();
    }
    );;
    cout << "started software" << endl;
    while(1) {
        std::mutex mutex;
        std::unique_lock<std::mutex> lock(mutex);
        waitcv.wait(lock);
        cout << "Received data: " << event_id << endl;
    }
    return 0;
}

标签: c++redis

解决方案


不确定这里不是完全关闭,但在 https://cylix.github.io/cpp_redis/html/classcpp__redis_1_1subscriber.html#ab7feafca57399394e3a1a0d6daf52770

他们说:cpp_redis::subscriber 用于与 Redis 服务器进行 PUB/SUB 通信。请不要使用 cpp_redis::client 订阅某些 Redis 频道:

  • 行为未定义
  • cpp_redis::client 不是为了那个

希望这可以帮助。(我自己还在为PUB/SUB苦苦挣扎,所以我没有解决方案)


推荐阅读