redis在游戏服务器中的使用初探(二) 客户端开源库选择

上文提到 搭建完成后 我们选择客户端的开源库进行连接 有以下三种选择 

1 acl-redis 原因是支持VC 国产  作者博客   acl 框架库简介  用 acl 库编写高效的 C++ redis 客户端应用

代码支持VC编译 最好使用vc2008-vc2012编译,这样工程包含redis的示例。 我选择的是vc2017的工程图标打开工程的,所以没有示例

作者有中文博客 对该库有详细的介绍 还有QQ群可以进行讨论 技术支持比较强大。

但是问题在于 整个工程偏向C风格 居然是用自己的thread和string。

C++工程若选择该库,在使用何种风格和多线程字符串等使用方式上会收到一定的约束

2 也可以选择 上面提到的redis工程中已经封装好的hredis 可参考我的这篇文章   windows下使用redis c++    。

这个库是redis工程中就包含的 原版匹配,原本是最佳选择。作为本系列演示操作

 

3 cpp_redis    地址 https://github.com/cylix/cpp_redis + https://github.com/Cylix/tacopie/tree/8714fcec4ba9694fb00e83e788aadc099bd0fd5d 

 这个感觉是最适合开始使用的库了 c++11 轻量级 跨平台的 redis客户端

不过稳定性和效率还需要再行观察

选定库后 来个简短的例子 测试下。 代码我稍微封装了下 使用了模板,在输入不同的类型时候根据模板自动匹配到相应的类型操作函数上

  1 // myRedisCli.cpp: 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <assert.h>
  6 #include <winsock2.h>
  7 #include <string.h>
  8 #include <tuple>
  9 #include <iostream>
 10 #include <sstream>
 11 #include <string.h>
 12 #include"hiredis/hiredis.h"
 13 
 14 
 15 class RedisConnect {
 16 public:
 17     RedisConnect() :redisCon(nullptr), reply(nullptr) {}
 18 
 19     bool Init(const std::string& ip, int port) {
 20         if (nullptr != redisCon) {
 21             return false;
 22         }
 23         redisCon = redisConnect(ip.c_str(), port);
 24         if (redisCon->err) {
 25             std::cerr << "error code : " << redisCon->err << ". " << redisCon->errstr << std::endl;
 26             return false;
 27         }
 28 
 29         return true;
 30     }
 31     void freeReply()
 32     {
 33         if (nullptr != reply)
 34         {
 35             ::freeReplyObject(reply);
 36             reply = nullptr;
 37         }
 38     }
 39 
 40     template<class T>
 41     bool GetVal(const std::string& key, T& value) {
 42         return Get(key, value);
 43     }
 44 
 45     template<class T, class... Args>
 46     bool HashSet(const std::string command, T head, Args... rest) {
 47         std::stringstream ss;
 48         ss << command << " " << head << " ";
 49         return HashSetInner(ss, rest...);
 50     }
 51 
 52     template<typename T>
 53     bool Set(const std::string & key, const T& value)
 54     {
 55         bool bret = false;
 56         std::stringstream ss;
 57         ss << "SET " << key << " " << value;
 58         std::string s;
 59         getline(ss, s);
 60         return Set(s);
 61     }
 62 
 63 
 64     bool InitWithTimeout(const std::string& ip, int port, int seconds) {
 65         if (nullptr != redisCon) {
 66             return false;
 67         }
 68         struct timeval tv;
 69         tv.tv_sec = seconds;
 70         tv.tv_usec = 0;
 71         redisCon = redisConnectWithTimeout(ip.c_str(), port, tv);
 72         if (redisCon->err) {
 73             std::cerr << "error code : " << redisCon->err << ". " << redisCon->errstr << std::endl;
 74             return false;
 75         }
 76         return true;
 77     }
 78 
 79     ~RedisConnect() {
 80         freeReply();
 81         if (nullptr == redisCon) {
 82             redisFree(redisCon);
 83             redisCon = nullptr;
 84         }
 85     }
 86 private:
 87     void GetString(const std::string & key)
 88     {
 89         freeReply();
 90         reply = (redisReply*)::redisCommand(redisCon, "GET %s", key.c_str());
 91     }
 92 
 93     bool Get(const std::string& key, std::string & value) {
 94         bool bret = false;
 95         GetString(key);
 96         if (nullptr == reply) {
 97             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
 98             return bret;
 99         }
100         else if (reply->type == REDIS_REPLY_NIL) {
101             std::cout << __FUNCTION__ << ". Key = "" << key << "" find nothing" << std::endl << std::endl;
102             return bret;
103         }else if( reply->type != REDIS_REPLY_STRING) {
104             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
105             return bret;
106         }
107         value = reply->str;
108         bret = true;
109         return bret;
110     }
111 
112     bool Get(const std::string& key, int & value) {
113         bool bret = false;
114         GetString(key);
115         if (nullptr == reply) {
116             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
117             return bret;
118         }
119         else if (reply->type == REDIS_REPLY_NIL) {
120             std::cout << __FUNCTION__ << ". Key = "" << key << "" find nothing" << std::endl << std::endl;
121             return bret;
122         }
123         else if (reply->type != REDIS_REPLY_STRING) {
124             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
125             return bret;
126         }
127         value = ::atoi(reply->str);
128         bret = true;
129         return bret;
130     }
131 
132     bool Get(const std::string& key, float & value) {
133         bool bret = false;
134         GetString(key);
135         if (nullptr == reply) {
136             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
137             return bret;
138         }
139         else if (reply->type == REDIS_REPLY_NIL) {
140             std::cout << __FUNCTION__ << ". Key = "" << key << "" find nothing" << std::endl << std::endl;
141             return bret;
142         }
143         else if (reply->type != REDIS_REPLY_STRING) {
144             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
145             return bret;
146         }
147         value = ::atof(reply->str);
148         bret = true;
149         return bret;
150     }
151 
152     bool HashSetInner(std::stringstream& ss)
153     {
154         std::string data;
155         getline(ss, data);
156         //std::cout << __FUNCTION__ << " " << data << std::endl;
157         bool bret = false;
158         freeReply();
159         reply = (redisReply*)::redisCommand(redisCon, data.c_str());
160 
161         if (reply->type == REDIS_REPLY_ERROR ||
162             (reply->type == REDIS_REPLY_STATUS && _stricmp(reply->str, "OK") != 0))
163         {
164             if (reply->str != nullptr) {
165                 std::cout << reply->str << std::endl;
166             }
167             std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
168             return bret;
169         }
170 
171         bret = true;
172 
173         return bret;
174     }
175 
176     template<class T, class... Args>
177     bool HashSetInner(std::stringstream& ss, T head, Args... rest)
178     {
179         ss << head << " ";
180         return HashSetInner(ss, rest...);
181     }
182 
183     bool Set(std::string data)
184     {
185         bool bret = false;
186         freeReply();
187         reply = (redisReply*)::redisCommand(redisCon, data.c_str());
188 
189         if (!(reply->type == REDIS_REPLY_STATUS && _stricmp(reply->str, "OK") == 0))
190         {
191             std::cout << reply->str << std::endl;
192             std::cout << "Failed to execute " << __FUNCTION__ << std::endl;
193             return bret;
194         }
195         bret = true;
196         return bret;
197     }
198 
199     redisContext* redisCon;
200     redisReply * reply;
201 };
202 
203 
204 
205 
206 int main()
207 {
208     RedisConnect r;
209 
210     bool b = r.InitWithTimeout("127.0.0.1", 6379, 5);
211     if (!b)
212         return -1;
213 
214     r.Set("testtimes", 1);
215     r.Set("float:pi", 3.14159265);
216     r.Set("string", "test");
217     std::string retStr;
218     r.GetVal("string", retStr);
219     float f;
220     r.GetVal("float:pi", f);
221     int i;
222     r.GetVal("testtimes", i);
223 
224     r.GetVal("wqe42", retStr);
225 
226     r.HashSet("hset", "myhash", "field1", 123.2342343);
227     r.HashSet("hmset", "myhash", "field1", 1111, "field2", "f2");
228     
229 
230 
231     r.HashSet("hset", "myhash", "field1", 123.2342343);
232     r.HashSet("hmset", "myhash", "field1", 1111, "field2", "f2");
233 
234     //wrong command
235     //r.HashSet("hset", "myhash", "field1", 1, 123.2342343);
236     //r.HashSet("hmset", "myhash", "field1", 1, 1111, "field2", "f2");
237 
238     std::cout << "finish !" << std::endl;
239     return 0;
240 }
MyHredisCli

运行效果图:(记得开启redis)

作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/9554676.html