int Ardb::UnsubscribeChannel(Context& ctx, const std::string& channel, bool notify) { ctx.GetPubsub().pubsub_channels.erase(channel); WriteLockGuard<SpinRWLock> guard(m_pubsub_ctx_lock); PubsubContextTable::iterator it = m_pubsub_channels.find(channel); int ret = 0; if (it != m_pubsub_channels.end()) { it->second.erase(&ctx); if (it->second.empty()) { m_pubsub_channels.erase(it); } ret = 1; } if (notify && NULL != ctx.client) { RedisReply r; RedisReply& r1 = r.AddMember(); RedisReply& r2 = r.AddMember(); RedisReply& r3 = r.AddMember(); fill_str_reply(r1, "unsubscribe"); fill_str_reply(r2, channel); fill_int_reply(r3, ctx.GetPubsub().pubsub_channels.size() + ctx.GetPubsub().pubsub_patterns.size()); ctx.client->Write(r); } return ret; }
int Ardb::UnsubscribeAll(Context& ctx, bool notify) { if(NULL == ctx.pubsub) { return 0; } StringSet tmp = ctx.GetPubsub().pubsub_channels; StringSet::iterator it = tmp.begin(); int count = 0; while (it != tmp.end()) { count += UnsubscribeChannel(ctx, *it, notify); it++; } if (notify && count == 0 && NULL != ctx.client) { RedisReply r; RedisReply& r1 = r.AddMember(); RedisReply& r2 = r.AddMember(); RedisReply& r3 = r.AddMember(); fill_str_reply(r1, "unsubscribe"); r2.type = REDIS_REPLY_NIL; fill_int_reply(r3, ctx.GetPubsub().pubsub_channels.size() + ctx.GetPubsub().pubsub_patterns.size()); ctx.client->Write(r); } return 0; }
int Ardb::SubscribeChannel(Context& ctx, const std::string& channel, bool notify) { ctx.GetPubsub().pubsub_channels.insert(channel); { WriteLockGuard<SpinRWLock> guard(m_pubsub_ctx_lock); m_pubsub_channels[channel].insert(&ctx); } if (notify && NULL != ctx.client) { RedisReply r; RedisReply& r1 = r.AddMember(); RedisReply& r2 = r.AddMember(); RedisReply& r3 = r.AddMember(); fill_str_reply(r1, "subscribe"); fill_str_reply(r2, channel); fill_int_reply(r3, ctx.GetPubsub().pubsub_channels.size() + ctx.GetPubsub().pubsub_patterns.size()); ctx.client->Write(r); } return 0; }