@@ -10,6 +10,7 @@ redis_subscriber::redis_subscriber(const std::shared_ptr<network::io_service>& I
1010}
1111
1212redis_subscriber::~redis_subscriber (void ) {
13+ m_client.disconnect ();
1314 __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber destroyed" );
1415}
1516
@@ -40,23 +41,23 @@ redis_subscriber::is_connected(void) {
4041}
4142
4243redis_subscriber&
43- redis_subscriber::subscribe (const std::string& channel, const subscribe_callback_t & callback) {
44+ redis_subscriber::subscribe (const std::string& channel, const subscribe_callback_t & callback, const acknowledgement_callback_t & acknowledgement_callback ) {
4445 std::lock_guard<std::mutex> lock (m_subscribed_channels_mutex);
4546
4647 __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber attemps to subscribe to channel " + channel);
47- m_subscribed_channels[channel] = callback;
48+ m_subscribed_channels[channel] = { callback, acknowledgement_callback} ;
4849 m_client.send ({" SUBSCRIBE" , channel});
4950 __CPP_REDIS_LOG (info, " cpp_redis::redis_subscriber subscribed to channel " + channel);
5051
5152 return *this ;
5253}
5354
5455redis_subscriber&
55- redis_subscriber::psubscribe (const std::string& pattern, const subscribe_callback_t & callback) {
56+ redis_subscriber::psubscribe (const std::string& pattern, const subscribe_callback_t & callback, const acknowledgement_callback_t & acknowledgement_callback ) {
5657 std::lock_guard<std::mutex> lock (m_psubscribed_channels_mutex);
5758
5859 __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber attemps to psubscribe to channel " + pattern);
59- m_psubscribed_channels[pattern] = callback;
60+ m_psubscribed_channels[pattern] = { callback, acknowledgement_callback} ;
6061 m_client.send ({" PSUBSCRIBE" , pattern});
6162 __CPP_REDIS_LOG (info, " cpp_redis::redis_subscriber psubscribed to channel " + pattern);
6263
@@ -114,6 +115,40 @@ redis_subscriber::commit(void) {
114115 return *this ;
115116}
116117
118+ void
119+ redis_subscriber::call_acknowledgement_callback (const std::string& channel, const std::map<std::string, callback_holder>& channels, std::mutex& channels_mtx, int nb_chans) {
120+ std::lock_guard<std::mutex> lock (channels_mtx);
121+
122+ auto it = channels.find (channel);
123+ if (it == channels.end ())
124+ return ;
125+
126+ if (it->second .acknowledgement_callback ) {
127+ __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber executes acknowledgement callback for channel " + channel);
128+ it->second .acknowledgement_callback (nb_chans);
129+ }
130+ }
131+
132+ void
133+ redis_subscriber::handle_acknowledgement_reply (const std::vector<reply>& reply) {
134+ if (reply.size () != 3 )
135+ return ;
136+
137+ const auto & title = reply[0 ];
138+ const auto & channel = reply[1 ];
139+ const auto & nb_chans = reply[2 ];
140+
141+ if (!title.is_string ()
142+ || !channel.is_string ()
143+ || !nb_chans.is_integer ())
144+ return ;
145+
146+ if (title.as_string () == " subscribe" )
147+ call_acknowledgement_callback (channel.as_string (), m_subscribed_channels, m_subscribed_channels_mutex, nb_chans.as_integer ());
148+ else if (title.as_string () == " psubscribe" )
149+ call_acknowledgement_callback (channel.as_string (), m_psubscribed_channels, m_psubscribed_channels_mutex, nb_chans.as_integer ());
150+ }
151+
117152void
118153redis_subscriber::handle_subscribe_reply (const std::vector<reply>& reply) {
119154 if (reply.size () != 3 )
@@ -138,7 +173,7 @@ redis_subscriber::handle_subscribe_reply(const std::vector<reply>& reply) {
138173 return ;
139174
140175 __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber executes subscribe callback for channel " + channel.as_string ());
141- it->second (channel.as_string (), message.as_string ());
176+ it->second . subscribe_callback (channel.as_string (), message.as_string ());
142177}
143178
144179void
@@ -167,7 +202,7 @@ redis_subscriber::handle_psubscribe_reply(const std::vector<reply>& reply) {
167202 return ;
168203
169204 __CPP_REDIS_LOG (debug, " cpp_redis::redis_subscriber executes psubscribe callback for channel " + channel.as_string ());
170- it->second (channel.as_string (), message.as_string ());
205+ it->second . subscribe_callback (channel.as_string (), message.as_string ());
171206}
172207
173208void
@@ -180,10 +215,13 @@ redis_subscriber::connection_receive_handler(network::redis_connection&, reply&
180215
181216 auto & array = reply.as_array ();
182217
183- // ! Array size of 3 -> SUBSCRIBE
218+ // ! Array size of 3 -> SUBSCRIBE if array[2] is a string
219+ // ! Array size of 3 -> AKNOWLEDGEMENT if array[2] is an integer
184220 // ! Array size of 4 -> PSUBSCRIBE
185221 // ! Otherwise -> unexepcted reply
186- if (array.size () == 3 )
222+ if (array.size () == 3 && array[2 ].is_integer ())
223+ handle_acknowledgement_reply (array);
224+ else if (array.size () == 3 && array[2 ].is_string ())
187225 handle_subscribe_reply (array);
188226 else if (array.size () == 4 )
189227 handle_psubscribe_reply (array);
0 commit comments