/* Subscribe a client to a channel. Returns 1 if the operation succeeded, or * 0 if the client was already subscribed to that channel. */ int pubsubSubscribeChannel(client *c, robj *channel) { dictEntry *de; list *clients = NULL; int retval = 0; /* Add the channel to the client -> channels hash table */ if (dictAdd(c->pubsub_channels,channel,NULL) == DICT_OK) { retval = 1; incrRefCount(channel); /* Add the client to the channel -> list of clients hash table */ de = dictFind(server.pubsub_channels,channel); if (de == NULL) { clients = listCreate(); dictAdd(server.pubsub_channels,channel,clients); incrRefCount(channel); } else { clients = dictGetVal(de); } listAddNodeTail(clients,c); } /* Notify the client */ addReply(c,shared.mbulkhdr[3]); addReply(c,shared.subscribebulk); addReplyBulk(c,channel); addReplyLongLong(c,clientSubscriptionsCount(c)); return retval; }
/* 频道订阅,即设置客户端订阅频道,如果操作成功返回1,如果该客户端已经订阅了指定频道则返回0 */ int pubsubSubscribeChannel(redisClient *c, robj *channel) { dictEntry *de; list *clients = NULL; int retval = 0; /* Add the channel to the client -> channels hash table */ // 将频道channel添加到client -> channels哈希表中 if (dictAdd(c->pubsub_channels,channel,NULL) == DICT_OK) { retval = 1; incrRefCount(channel); /* Add the client to the channel -> list of clients hash table */ // server.pubsub_channels中保存了Redis服务器中所有频道和其相关客户端的信息 // 先判断给定频道是否存在于server.pubsub_channels字典中 de = dictFind(server.pubsub_channels,channel); if (de == NULL) { // 频道不存在,则将其加入server.pubsub_channels中 clients = listCreate(); dictAdd(server.pubsub_channels,channel,clients); incrRefCount(channel); } else { clients = dictGetVal(de); } // 将客户端添加到指定频道对应的客户端链表中 listAddNodeTail(clients,c); } /* Notify the client */ // 回复客户端 addReply(c,shared.mbulkhdr[3]); addReply(c,shared.subscribebulk); addReplyBulk(c,channel); addReplyLongLong(c,clientSubscriptionsCount(c)); return retval; }
/* 模式订阅,即设置客户端订阅某模式。如果订阅成功则返回1,如果客户端已经订阅了该模式则返回0。*/ int pubsubSubscribePattern(redisClient *c, robj *pattern) { int retval = 0; // 先在客户端的c->pubsub_patterns链表中查找,判断客户端是否已经订阅了该模式 if (listSearchKey(c->pubsub_patterns,pattern) == NULL) { // 客户端并没有订阅该模式 retval = 1; pubsubPattern *pat; // 将制定模式添加到c->pubsub_patterns链表中 listAddNodeTail(c->pubsub_patterns,pattern); incrRefCount(pattern); pat = zmalloc(sizeof(*pat)); pat->pattern = getDecodedObject(pattern); pat->client = c; // 将pubsubPattern结构添加到server.pubsub_patterns链表中 listAddNodeTail(server.pubsub_patterns,pat); } /* Notify the client */ // 回复客户端 addReply(c,shared.mbulkhdr[3]); // 回复“psubscribe”字符串 addReply(c,shared.psubscribebulk); // 回复被订阅的模式字符串 addReplyBulk(c,pattern); // 回复客户端订阅的频道和模式总数目 addReplyLongLong(c,clientSubscriptionsCount(c)); return retval; }
void punsubscribeCommand(client *c) { if (c->argc == 1) { pubsubUnsubscribeAllPatterns(c,1); } else { int j; for (j = 1; j < c->argc; j++) pubsubUnsubscribePattern(c,c->argv[j],1); } if (clientSubscriptionsCount(c) == 0) c->flags &= ~CLIENT_PUBSUB; }
/* unsbuscribe退订频道命令 */ void unsubscribeCommand(redisClient *c) { if (c->argc == 1) { pubsubUnsubscribeAllChannels(c,1); } else { int j; for (j = 1; j < c->argc; j++) pubsubUnsubscribeChannel(c,c->argv[j],1); } if (clientSubscriptionsCount(c) == 0) c->flags &= ~REDIS_PUBSUB; }
/* Subscribe a client to a pattern. Returns 1 if the operation succeeded, or 0 if the client was already subscribed to that pattern. */ int pubsubSubscribePattern(client *c, robj *pattern) { int retval = 0; if (listSearchKey(c->pubsub_patterns,pattern) == NULL) { retval = 1; pubsubPattern *pat; listAddNodeTail(c->pubsub_patterns,pattern); incrRefCount(pattern); pat = zmalloc(sizeof(*pat)); pat->pattern = getDecodedObject(pattern); pat->client = c; listAddNodeTail(server.pubsub_patterns,pat); } /* Notify the client */ addReply(c,shared.mbulkhdr[3]); addReply(c,shared.psubscribebulk); addReplyBulk(c,pattern); addReplyLongLong(c,clientSubscriptionsCount(c)); return retval; }