redis是高效key-value NOSQL 数据库 代码开源
windows下使用需要使用微软在redis官方上的改进版
地址 https://redis.io/download
寻找windows的版本
https://github.com/MicrosoftArchive/redis
我这里下载的是windows版本redis 3.0版本 使用vs2017编译
由于是微软官方的redis改变版本 使用VS编译基本无问题
需要注意的是hiredis工程 生成的是LIB文件供其他连接redis的项目使用
但是该工程调用了Win32_Interop项目代码,所以使用时候需要同时提供Win32_Interop.lib hiredis.lib。
此时项目编译的结果应该是 成功编译redis-server.exe 并且有Win32_Interop.lib hiredis.lib可供我们编写客户端使用。
参考 https://www.cnblogs.com/chinxi/p/6184885.html 添加模板结构
客户端的编写
新建工程。工程里面放入 Win32_Interop.lib hiredis.lib
加入 hiredis相关和Win32_Interop相关头文件
注意 hiredis.h头文件中
#include "../../src/Win32_Interop/win32_types_hiredis.h"
两个头文件的相对路径可能需要修改
代码如下
// MyRedisTest.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include"hiredis/hiredis.h"
class RedisConnect {
public:
RedisConnect() :redisCon(nullptr), reply(nullptr) {}
bool Init(const std::string& ip, int port) {
if (nullptr != redisCon) {
return false;
}
redisCon = redisConnect(ip.c_str(), port);
if (redisCon->err) {
std::cerr << "error code : " << redisCon->err << ". " << redisCon->errstr << std::endl;
return false;
}
return true;
}
void freeReply()
{
if (nullptr != reply)
{
::freeReplyObject(reply);
reply = nullptr;
}
}
template
bool HashSet(const std::string command,T head, Args... rest) {
std::stringstream ss;
ss << command << " " << head << " " ;
return HashSetInner(ss,rest...);
}
template
bool Set(const std::string & key, const T& value)
{
bool bret = false;
std::stringstream ss;
ss << "SET " << key << " " << value;
std::string s;
getline(ss, s);
return Set(s);
}
bool InitWithTimeout(const std::string& ip, int port, int seconds) {
if (nullptr != redisCon) {
return false;
}
struct timeval tv;
tv.tv_sec = seconds;
tv.tv_usec = 0;
redisCon = redisConnectWithTimeout(ip.c_str(), port, tv);
if (redisCon->err) {
std::cerr << "error code : " << redisCon->err << ". " << redisCon->errstr << std::endl;
return false;
}
return true;
}
~RedisConnect() {
freeReply();
if(nullptr == redisCon){
redisFree(redisCon);
redisCon = nullptr;
}
}
private:
bool HashSetInner(std::stringstream& ss)
{
std::string data;
getline(ss, data);
//std::cout << __FUNCTION__ << " " << data << std::endl;
bool bret = false;
freeReply();
reply = (redisReply*)::redisCommand(redisCon, data.c_str());
if (reply->type == REDIS_REPLY_ERROR ||
(reply->type == REDIS_REPLY_STATUS && _stricmp(reply->str, "OK") != 0))
{
if (reply->str != nullptr) {
std::cout << reply->str << std::endl;
}
std::cout << "Failed to execute " << __FUNCTION__ << std::endl << std::endl;
return bret;
}
bret = true;
return bret;
}
template
bool HashSetInner(std::stringstream& ss, T head, Args... rest)
{
ss << head << " ";
return HashSetInner(ss, rest...);
}
bool Set(std::string data)
{
bool bret = false;
freeReply();
reply = (redisReply*)::redisCommand(redisCon, data.c_str());
if (!(reply->type == REDIS_REPLY_STATUS && _stricmp(reply->str, "OK") == 0))
{
std::cout << reply->str << std::endl;
std::cout << "Failed to execute " << __FUNCTION__ << std::endl;
return bret;
}
bret = true;
return bret;
}
redisContext* redisCon;
redisReply * reply;
};
int main()
{
RedisConnect r;
bool b = r.InitWithTimeout("127.0.0.1", 6379,1);
if (!b)
return -1;
r.Set("testtimes",1);
r.Set("float:pi", 3.14159265);
r.Set("string","test");
r.HashSet("hset", "myhash", "field1", 123.2342343);
r.HashSet("hmset", "myhash", "field1",1111,"field2","f2");
r.HashSet("hset", "myhash", "field1", 123.2342343);
r.HashSet("hmset", "myhash", "field1", 1111, "field2", "f2");
//wrong command
r.HashSet("hset", "myhash", "field1",1, 123.2342343);
r.HashSet("hmset", "myhash", "field1",1, 1111, "field2", "f2");
return 0;
}