6
6
#include " hiredis/async.h"
7
7
#include " hiredis/adapters/libuv.h"
8
8
9
- /* Todo: send redis PING every 10 seconds */
10
-
11
9
#include " App.h"
12
10
13
11
/* We use libuv to share the same event loop across hiredis and uSockets */
@@ -22,6 +20,9 @@ const char *redisHostname;
22
20
int redisPort;
23
21
const char *redisTopic;
24
22
23
+ /* We use this to ping Redis */
24
+ uv_timer_t pingTimer;
25
+
25
26
void onMessage (redisAsyncContext *c, void *reply, void *privdata);
26
27
27
28
/* Connect to Redis server, manages reconnect by calling itself when needed */
@@ -56,6 +57,9 @@ redisAsyncContext *connectToRedis(uWS::App *app) {
56
57
});
57
58
58
59
redisAsyncSetDisconnectCallback (c, [](const redisAsyncContext *c, int status) {
60
+ /* We are no longer connected to Redis, so stop pinging it */
61
+ pingTimer.data = nullptr ;
62
+
59
63
if (status != REDIS_OK) {
60
64
printf (" Lost connection to Redis: %s\n " , c->errstr );
61
65
@@ -87,6 +91,8 @@ void onMessage(redisAsyncContext *c, void *reply, void *privdata) {
87
91
return ;
88
92
}
89
93
94
+ /* PONG responses are discarded by hiredis even though they technically reach us */
95
+
90
96
if (r->type == REDIS_REPLY_ARRAY) {
91
97
/* We always expect action, topic, message */
92
98
if (r->elements == 3 ) {
@@ -104,6 +110,7 @@ void onMessage(redisAsyncContext *c, void *reply, void *privdata) {
104
110
printf (" We are connected and subscribed to Redis now\n " );
105
111
106
112
/* Start a timer sending Pings to Redis */
113
+ pingTimer.data = c;
107
114
}
108
115
}
109
116
}
@@ -152,6 +159,18 @@ int main() {
152
159
uWS::Loop::get (uv_default_loop ());
153
160
uWS::App app;
154
161
162
+ /* Start a timer sending pings to Redis every 10 seconds */
163
+ uv_timer_init (uv_default_loop (), &pingTimer);
164
+ pingTimer.data = nullptr ;
165
+ uv_timer_start (&pingTimer, [](uv_timer_t *t) {
166
+ /* We store currently connected Redis context in user data */
167
+ redisAsyncContext *c = (redisAsyncContext *) t->data ;
168
+
169
+ /* Redis does respond with a PONG but hiredis bugs discard it so the callback is never called.
170
+ * For us this doesn't matter as we only want to send something to trigger errors on the socket if so */
171
+ redisAsyncCommand ((redisAsyncContext *) c, onMessage, c->data , " PING" );
172
+ }, 10000 , 10000 );
173
+
155
174
/* Connect to Redis, this will automatically keep reconnecting once disconnected */
156
175
connectToRedis (&app);
157
176
0 commit comments