最近在用redis的pub\sub功能来实现群发消息,控制6个类似的软件,但是在使用pub\sub的管理代码时发现了一个有趣的事情,特意记录下来,以免日后忘记。
PubSubManager.cpp中有一段特有意思的代码:
void PubSubManager::PrintReply( redisReply *reply )
{
switch (reply->type)
{
case REDIS_REPLY_INTEGER:
// DEBUGLOG("[Integer] %d", reply->integer);
break;
case REDIS_REPLY_ERROR:
case REDIS_REPLY_STRING:
//DEBUGLOG(reply->str);
if (!strcasecmp(reply->str, "save")) /*pub/sub的返回值:sub——1) "subscribe"
2) "CCDCaptureSync"
3) (integer) 1
pub——1) "message"
2) "CCDCaptureSync"
3) "save"
因此判断语句中用信息作为关键字(如“save”),或者用“subscribe”、“message”、“CCDCaptureSync”作为关键字,这句代码都会起作用,
但是只有pub的信息,即第三个元素是我们关心的,此处为save。
*/
{
SAVEAPICTURE();
}
else if (!strcasecmp(reply->str, "detect"))
{
//按下detect按钮
}
else if (!strcasecmp(reply->str, "start"))
{
//按下start按钮
}
else if (!strcasecmp(reply->str, "stop"))
{
//按下stop按钮
}
else if (!strcasecmp(reply->str, "exit"))
{
//按下exit按钮
}
break;
case REDIS_REPLY_ARRAY:
if (reply->element)
{
for (int i = 0; i < reply->elements; i++)
{
PrintReply(reply->element[i]); //返回是数组的还会递归调用PrintReply,判断数组中的成员reply->element[i]是数字还是字符串,每个元素都会遍及
}
}
break;
}
}
我在注释中已经写得比较清楚了。这个采集redis返回值的函数中可以对pub和sub都起作用,由于pub\sub中的返回值是数组,而有用的信息存在于数组中,可以采用数组指针的方式找到对应的元素。其实类似的还有list中的BLPOP,它的返回值也是数组。
这个函数巧妙地使用递归法,可以把返回值中的元素都提取出来。需要注意的是,代码中的elements是元素的数量。而element[i]是表示第i个元素。
pub\sub的管理包可在hiredis的pub\sub管理代码下载。