Skip to content

Commit 41faa20

Browse files
DOC-4997 added libevent guide, index page and fixes
1 parent c9f74f4 commit 41faa20

File tree

4 files changed

+212
-9
lines changed

4 files changed

+212
-9
lines changed

content/develop/clients/hiredis/connect.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ redisFree(c);
6767
You can also connect to Redis using an asynchronous API.
6868
The `redisAsyncConnect()` call that creates the context is
6969
similar to the synchronous function `redisConnect()`, but it returns the
70-
context object immediately and lets you supply callbacks to
71-
check the connection and handle any errors that may occur.
70+
context object immediately before the connection is complete.
71+
It lets you supply callbacks to respond when a connection is successful
72+
or to handle any errors that may occur.
7273
7374
The following code creates an asynchronous connection and
7475
sets the context callbacks:
@@ -105,7 +106,7 @@ redisAsyncCommand(c, getCallback, key, "GET %s", key);
105106
```
106107

107108
The callback functions have a simple signature that receives
108-
the context object and a status code as parameters. See
109+
the context object and a status code. See
109110
[Handling errors]({{< relref "/develop/clients/hiredis/handle-replies#handling-errors" >}})
110111
for a list of the possible status codes.
111112

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Integrate hiredis with C++ and external frameworks.
13+
linkTitle: Integration guides
14+
title: Integration guides
15+
weight: 50
16+
---
17+
18+
`hiredis` is compatible with C++ and the library source includes a set of
19+
[adapters](https://github.com/redis/hiredis/tree/master/adapters)
20+
to help you use it in conjunction with C and C++ libraries and frameworks.
21+
The pages in this section explain how to integrate `hiredis` into
22+
your app.
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Use `hiredis` in conjunction with the `libevent` framework.
13+
linkTitle: libevent integration
14+
title: Integrate hiredis with a libevent app
15+
weight: 60
16+
---
17+
18+
The [`libevent`](https://libevent.org/) library provides an
19+
implementation of an event loop that lets you call functions
20+
asynchronously in response to events. This guide explains
21+
how to use `hiredis` to connect to a Redis server from a
22+
`libevent` app.
23+
24+
## Install `libevent`
25+
26+
The [`libevent` home page](https://libevent.org/) has links to download
27+
all versions of the library, but you should use the latest version
28+
unless there is a specific version you need to target.
29+
30+
When you have downloaded `libevent`, follow the instructions in the
31+
`README` file to compile and install the library.
32+
33+
## Create a simple app
34+
35+
For a real project, you would build your code with a makefile, but for
36+
this simple test, you can just place it in a file called `main.c` and
37+
build it with the following command (assuming you used `make install` to
38+
install the `libhiredis` and `libevent` libraries):
39+
40+
```bash
41+
cc main.c -L/usr/local/lib -lhiredis -levent
42+
```
43+
44+
See [Build and install]({{< relref "/develop/clients/hiredis#build-and-install" >}})
45+
to learn how to build `hiredis`, if you have not already done so.
46+
47+
Add the following header files from the `hiredis` folder to your project folder:
48+
49+
- `hiredis.h`
50+
- `async.h`
51+
- `adapters/libevent.h`
52+
53+
You should include the `libevent.h` file in a folder called `adapters` but you
54+
don't need the other headers in the original `adapters` folder for this
55+
example.
56+
57+
Now, add the following code in `main.c`. An explanation follows the
58+
code example:
59+
60+
```c
61+
#include <stdio.h>
62+
#include <stdlib.h>
63+
#include <string.h>
64+
#include <signal.h>
65+
66+
#include "hiredis.h"
67+
#include "async.h"
68+
#include "adapters/libevent.h"
69+
70+
// Callback for the `GET` command.
71+
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
72+
redisReply *reply = r;
73+
char *key = privdata;
74+
75+
if (reply == NULL) {
76+
if (c->errstr) {
77+
printf("errstr: %s\n", c->errstr);
78+
}
79+
return;
80+
}
81+
82+
printf("Key: %s, value: %s\n", key, reply->str);
83+
84+
/* Disconnect after receiving the reply to GET */
85+
redisAsyncDisconnect(c);
86+
}
87+
88+
// Callback to respond to successful or unsuccessful connection.
89+
void connectCallback(const redisAsyncContext *c, int status) {
90+
if (status != REDIS_OK) {
91+
printf("Error: %s\n", c->errstr);
92+
return;
93+
}
94+
printf("Connected...\n");
95+
}
96+
97+
// Callback to respond to intentional or unexpected disconnection.
98+
void disconnectCallback(const redisAsyncContext *c, int status) {
99+
if (status != REDIS_OK) {
100+
printf("Error: %s\n", c->errstr);
101+
return;
102+
}
103+
printf("Disconnected...\n");
104+
}
105+
106+
107+
int main (int argc, char **argv) {
108+
#ifndef _WIN32
109+
signal(SIGPIPE, SIG_IGN);
110+
#endif
111+
112+
// Create the libevent `event_base` object to track all
113+
// events.
114+
struct event_base *base = event_base_new();
115+
116+
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
117+
118+
if (c->err) {
119+
printf("Error: %s\n", c->errstr);
120+
return 1;
121+
}
122+
123+
// Use the Redis libevent adapter to attach the Redis connection
124+
// to the libevent main loop.
125+
redisLibeventAttach(c,base);
126+
127+
redisAsyncSetConnectCallback(c, connectCallback);
128+
redisAsyncSetDisconnectCallback(c, disconnectCallback);
129+
130+
char *key = "testkey";
131+
char *value = "testvalue";
132+
133+
redisAsyncCommand(c, NULL, NULL, "SET %s %s", key, value);
134+
redisAsyncCommand(c, getCallback, key, "GET %s", key);
135+
136+
// Run the event loop.
137+
event_base_dispatch(base);
138+
139+
return 0;
140+
}
141+
```
142+
143+
The code calls
144+
[`event_base_new()`](https://libevent.org/doc/event_8h.html#af34c025430d445427a2a5661082405c3)
145+
to initialize the core
146+
[`event_base`](https://libevent.org/doc/structevent__base.html)
147+
object that manages the event loop. It then creates a standard
148+
[asynchronous connection]({{< relref "/develop/clients/hiredis/connect#asynchronous-connection" >}})
149+
to Redis and uses the `libevent` adapter function `redisLibeventAttach()` to
150+
attach the connection to the event loop.
151+
152+
After setting the [connection callbacks]({{< relref "/develop/clients/hiredis/connect#asynchronous-connection" >}}), the code issues two asynchronous
153+
Redis commands (see
154+
[Construct asynchronous commands]({{< relref "/develop/clients/hiredis/issue-commands#construct-asynchronous-commands" >}})
155+
for more information).
156+
The final step is to call
157+
[`event_base_dispatch()`](https://libevent.org/doc/event_8h.html#a19d60cb72a1af398247f40e92cf07056)
158+
to start the event loop. This will wait for the commands to be processed and
159+
then exit when the Redis connection is closed in the `getCallback()` function.
160+
161+
## Run the code
162+
163+
If you compile and run the code, you will see the following output,
164+
showing that the callbacks executed correctly:
165+
166+
```
167+
Connected...
168+
Key: testkey, value: testvalue
169+
Disconnected...
170+
```
171+
172+
You can use the
173+
[`KEYS`]({{< relref "/commands/keys" >}}) command from
174+
[`redis-cli`]({{< relref "/develop/tools/cli" >}}) or
175+
[Redis Insight]({{< relref "/develop/tools/insight" >}}) to check
176+
that the "testkey" string key was added to the Redis database.

content/develop/clients/hiredis/int-examples/qt-integration.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ You must do this because `qt.h` is in the same enclosing folder as `async.h` for
6868
this project.
6969

7070
You should also make the `libhiredis` library available to the project. For example,
71-
if you have used the default option of [`cmake`](https://cmake.org/) for the project
72-
build and you have installed the `.dylib` or `.so` file for `hiredis` in `/usr/local/lib`,
71+
if you have used the default option of [`cmake`](https://cmake.org/) as the project
72+
build tool and you have installed the `.dylib` or `.so` file for `hiredis` in `/usr/local/lib`,
7373
you should add the following lines to the `CMakeLists.txt` file:
7474

7575
```
@@ -168,8 +168,9 @@ Our simple example code just sets and gets a Redis
168168
private attributes for the key and value (following the Qt `m_xxx` naming convention
169169
for class members). These are set by the constructor along with a call to the
170170
`QObject` constructor. The other attributes represent the connection context for
171-
Redis (which should be asynchronous for a Qt app) and an adapter object that
172-
`hiredis` uses to integrate with Qt.
171+
Redis (which should generally be
172+
[asynchronous]({{< relref "/develop/clients/hiredis/connect#asynchronous-connection" >}})
173+
for a Qt app) and an adapter object that `hiredis` uses to integrate with Qt.
173174

174175
### Implementation file
175176

@@ -305,8 +306,11 @@ then creates the instance of `RedisExample` with the key ("url") and
305306
value ("https://redis.io/") for our Redis string.
306307

307308
The two lines below set up the `QObject` communication mechanism
308-
for the app. The call to `QTimer::singleShot()` activates the `run()`
309-
slot method on our `RedisExample` instance. The `QObject::connect()`
309+
for the app. The call to
310+
[`QTimer::singleShot()`](https://doc.qt.io/qt-6/qtimer.html#singleShot-2)
311+
activates the `run()`
312+
slot method on our `RedisExample` instance. The
313+
[`QObject::connect()`](https://doc.qt.io/qt-6/qobject.html#connect-5)
310314
call creates a communication link between the `finished()` signal of
311315
out `RedisExample` instance and the `quit()` slot of our
312316
`QCoreApplication` instance. This quits the application event loop and

0 commit comments

Comments
 (0)