https://github.com/nokia/wiredis
A C++ client for Redis (https://redis.io/)
https://github.com/nokia/wiredis
redis
Last synced: 10 months ago
JSON representation
A C++ client for Redis (https://redis.io/)
- Host: GitHub
- URL: https://github.com/nokia/wiredis
- Owner: nokia
- License: bsd-3-clause
- Created: 2018-11-05T07:35:03.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2020-08-06T14:01:15.000Z (almost 6 years ago)
- Last Synced: 2025-04-04T04:11:28.659Z (about 1 year ago)
- Topics: redis
- Language: C++
- Size: 24.4 KB
- Stars: 9
- Watchers: 8
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# wiredis
wiredis is a header-only, asynchronous c++11 client library for [redis](http://redis.io/) database server.
It depends only on [boost](https://www.boost.org/) library and uses [::boost::asio::io_service](https://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html) as event handler.
Tested on
- Arch linux
- cmake 3.11.4
- g++ 8.1.1
- boost 1.67
- Redhat
- cmake 3.12.0
- g++ 4.8.5
- boost 1.68
## Compile and install
```
$ mkdir build && cd build && cmake ../ && sudo make install
```
## Features
- Asynchronous interface
- Standalone: depends only on [boost](https://www.boost.org) library.
- Auto reconnect
- TCP keepalive on idle connection
- Exact match with redis commands without inner logic
- Binary key/values
- PUB/SUB mode
## Usage
You can find working examples under [examples](examples/) folder and full documention below in this document.
First of all you need a running ::boost::asio::io_service instance.
```
::boost::asio::io_service ios;
bool loop_condition = true;
std::thread scheduler_thread(
[&]
{
while (loop_condition)
{
ios.reset();
ios.run();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
});
```
...then create a `::nokia::net::redis_connection` instance:
```
::nokia::net::redis_connection con(ios);
con.connect("127.0.0.1",
6379,
[] (boost::system::error_code const & error)
{
if (error)
{
std::cout << "Connect failed. Keep trying..." << std::endl;
}
else
{
std::cout << "Connected!" << std::endl;
}
},
[&] (boost::system::error_code const & ec)
{
std::cout << "Connection lost. Error core: " << ec << ". Reconnecting..."<< std::endl;
});
```
Once the connection established you can start working on the connection.
To send a command to redis-server you need to invoke `execute()` function with a callback function, the command and the arguments of the command.
```
con.execute([&] (::nokia::net::proto::redis::reply && reply)
{
if (::nokia::net::proto::redis::reply::NIL == reply.type)
{
std::cout << "Key not found" << std::endl;
}
else
{
std::cout << "Key found. Value:" << reply.str << std::endl;
}
},
"GET", "key");
```
If you use multiple arguments you need to separate them:
```
con.execute([&] (::nokia::net::proto::redis::reply && reply)
{
if (::nokia::net::proto::redis::reply::NIL == reply.type)
{
std::cout << "Key not found" << std::endl;
}
else
{
std::cout << "Key found. Value:" << reply.str << std::endl;
}
},
"HSET", "key", "field", "value");
```
Return object has type `::nokia::net::proto::redis::reply &&` which follows the [RESP](https://redis.io/topics/protocol) definition.
```
struct reply
{
enum type
{
INVALID, // [w] only for debugging purpose
STRING,
INTEGER,
ARRAY,
NIL,
ERROR
};
type type;
std::string str;
int64_t integer;
std::vector elements;
};
```
To close your connection you need to use `join()` function.
```
con.disconnect();
con.join([] ()
{
std::cout << "Cleanup done, we can die now." << std::endl;
});
```
Alternatively, you can use `sync_join()` function but be warned: it uses the `io_service` object so never call from thread being run by your `io_service` object!
## [PUB/SUB](https://redis.io/topics/pubsub) mode
You can use redis connection to watch a given channel.
Note: once you switch to [PUB/SUB](https://redis.io/topics/pubsub) mode you can't use the conncetion for standard operations. Allowed commands in PUB/SUB mode: SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, PUNSUBSCRIBE, PING and QUIT.
```
con.subscribe("my-channel",
[&] ()
{
std::cout << "subscribed for channel \"my-channel\"" << std::endl;
},
[] (std::string const & channel, std::string const & message)
{
std::cout << "* Just get a message on channel \"" << channel << "\": " << message << std::endl;
},
[&] ()
{
std::cout << "* Unsubscribed from channel \"my-channel\"" << std::endl;
});
```
## Documentation
### redis_connection()
```
redis_connection(boost::asio::io_service & io_service);
```
Simply constructor to create redis_connection object.
- io_service: The `::boost::asio::io_service` you want to use for event handler.
### connect()
```
void connect(std::string const & ip,
uint16_t port,
std::function connected_callback,
std::function disconnected_callback,
bool auto_reconnect = true,
bool keepalive_enabled = true);
```
Initiate connecting to redis-server.
- ip: ip address of redis server.
- port: port of redis server.
- connected_callback: this function will be called every time the client connects to the server including reconnecting.
- disconnected_callback: this function will be called if the client losts conncection to server excluding the disconnect() function call.
- auto_reconnect: if it's true the client tries to reconnect to the server. After reconncection the connection is in standard mode, you lose every previous subscriptions.
- keepalive_enabled: if it's true the connection uses TCP keepaliving. The settings are
- TCP_KEEPIDLE: 2
- TCP_KEEPINTVL: 2
- TCP_KEEPCNT: 3
### connected()
```
bool connected() const;
```
Returns true if the connection is established.
### disconnect()
```
void disconnect();
```
Disconnect from redis server. Always use this function if you want tear-down, it performs clean-up.
### join(), sync_join()
```
void join(std::function cb);
void sync_join();
```
Waits for clean-up. The first version calls back once the clean-up has finished, while the second version blocks.
Note: `snyc_join()` uses the `io_service` object so never call from thread being run by your `io_service` object!
### execute()
```
template
void execute(std::function callback, Ts &&... ts);
```
Invoke redis command. The execution and return value are same as redis defines, there is no inner logic. See: https://redis.io/commands
Binary arguments are supported.
- callback: this function will be called with the result.
- ts: redis command and its arguments.
### subscribe(), psusbscribe()
```
void subscribe(std::string const & channel,
std::function subscribed_callback,
std::function change_callback,
std::function unsubscribed_callback);
void psubscribe(std::string const & pattern,
std::function subscribed_callback,
std::function pattern_change_callback,
std::function unsubscribed_callback);
```
Subscribe for a given channel/channel matches with the pattern.
If you already subscribed for a channel you will get `subscription_already_exists` exception.
- channel/pattern: the channel/pattern of channel you want to subscribe.
- subscribed_callback: this function will be called once the subscription is ready.
- change_callback: this function will be called if new message arrives on the subscribed channel.
- unsubscribed_callback: this function will be called if you've successfully unsubscribed from the channel.
### unsubscribe(), punsubscribe()
```
void unsubscribe(std::string const & channel);
void punsubscribe(std::string const & pattern);
```
Unsubscribe from a previously subscribed channel/pattern of channel.
If the subscription doesn't exist you'll get a `subscription_does_not_exist` exception.
- channel/pattern: the channel/pattern of channel you want to unsubscribe from.
### set_log_callback()
```
void set_log_callback(std::function cb);
```
The logs are printed out to stdout by default. If you want to handle by your own, you need to call this function with your callback function.
## Tests
To run unit tests, you need to have installed valgrind, redis-server and need to use Debug configuration.
Tests start/stop redis-server, so turn off redis-server if it runs: systemctl stop redis
```
mkdir build
cd build
cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Debug
ninja
ctest -T memcheck
```
## License
This project is licensed under the BSD-3-Clause license - see the [LICENSE](https://github.com/nokia/wiredis/blob/master/LICENSE).