@@ -79,92 +79,106 @@ int main(int argc, char** argv) {
79
79
mi_sub_con subs;
80
80
81
81
s.set_accept_handler (
82
- [&](con_t & ep) {
82
+ [&connections, &subs](con_sp_t spep) {
83
+ auto & ep = *spep;
84
+ std::weak_ptr<con_t > wp (spep);
85
+
83
86
using packet_id_t = typename std::remove_reference_t <decltype (ep)>::packet_id_t ;
84
87
std::cout << " accept" << std::endl;
85
- auto sp = ep.shared_from_this ();
86
- ep.start_session (sp); // keeping ep's lifetime as sp until session finished
88
+
89
+ // Pass spep to keep lifetime.
90
+ // It makes sure wp.lock() never return nullptr in the handlers below
91
+ // including close_handler and error_handler.
92
+ ep.start_session (std::move (spep));
87
93
88
94
// set connection (lower than MQTT) level handlers
89
95
ep.set_close_handler (
90
- [&]
96
+ [&connections, &subs, wp ]
91
97
(){
92
- std::cout << " closed." << std::endl;
93
- close_proc (connections, subs, ep.shared_from_this ());
98
+ std::cout << " [server] closed." << std::endl;
99
+ auto sp = wp.lock ();
100
+ BOOST_ASSERT (sp);
101
+ close_proc (connections, subs, sp);
94
102
});
95
103
ep.set_error_handler (
96
- [&]
104
+ [&connections, &subs, wp ]
97
105
(boost::system ::error_code const & ec){
98
- std::cout << " error: " << ec.message () << std::endl;
99
- close_proc (connections, subs, ep.shared_from_this ());
106
+ std::cout << " [server] error: " << ec.message () << std::endl;
107
+ auto sp = wp.lock ();
108
+ BOOST_ASSERT (sp);
109
+ close_proc (connections, subs, sp);
100
110
});
101
111
102
112
// set MQTT level handlers
103
113
ep.set_connect_handler (
104
- [&]
114
+ [&connections, wp ]
105
115
(MQTT_NS::buffer client_id,
106
116
MQTT_NS::optional<MQTT_NS::buffer> username,
107
117
MQTT_NS::optional<MQTT_NS::buffer> password,
108
118
MQTT_NS::optional<MQTT_NS::will>,
109
119
bool clean_session,
110
120
std::uint16_t keep_alive) {
111
121
using namespace MQTT_NS ::literals;
112
- std::cout << " client_id : " << client_id << std::endl;
113
- std::cout << " username : " << (username ? username.value () : " none" _mb) << std::endl;
114
- std::cout << " password : " << (password ? password.value () : " none" _mb) << std::endl;
115
- std::cout << " clean_session: " << std::boolalpha << clean_session << std::endl;
116
- std::cout << " keep_alive : " << keep_alive << std::endl;
117
- connections.insert (ep.shared_from_this ());
118
- ep.connack (false , MQTT_NS::connect_return_code::accepted);
122
+ std::cout << " [server] client_id : " << client_id << std::endl;
123
+ std::cout << " [server] username : " << (username ? username.value () : " none" _mb) << std::endl;
124
+ std::cout << " [server] password : " << (password ? password.value () : " none" _mb) << std::endl;
125
+ std::cout << " [server] clean_session: " << std::boolalpha << clean_session << std::endl;
126
+ std::cout << " [server] keep_alive : " << keep_alive << std::endl;
127
+ auto sp = wp.lock ();
128
+ BOOST_ASSERT (sp);
129
+ connections.insert (sp);
130
+ sp->connack (false , MQTT_NS::connect_return_code::accepted);
119
131
return true ;
120
132
}
121
133
);
122
134
ep.set_disconnect_handler (
123
- [&]
135
+ [&connections, &subs, wp ]
124
136
(){
125
- std::cout << " disconnect received." << std::endl;
126
- close_proc (connections, subs, ep.shared_from_this ());
137
+ std::cout << " [server] disconnect received." << std::endl;
138
+ auto sp = wp.lock ();
139
+ BOOST_ASSERT (sp);
140
+ close_proc (connections, subs, sp);
127
141
});
128
142
ep.set_puback_handler (
129
- [& ]
143
+ []
130
144
(packet_id_t packet_id){
131
- std::cout << " puback received. packet_id: " << packet_id << std::endl;
145
+ std::cout << " [server] puback received. packet_id: " << packet_id << std::endl;
132
146
return true ;
133
147
});
134
148
ep.set_pubrec_handler (
135
- [& ]
149
+ []
136
150
(packet_id_t packet_id){
137
- std::cout << " pubrec received. packet_id: " << packet_id << std::endl;
151
+ std::cout << " [server] pubrec received. packet_id: " << packet_id << std::endl;
138
152
return true ;
139
153
});
140
154
ep.set_pubrel_handler (
141
- [& ]
155
+ []
142
156
(packet_id_t packet_id){
143
- std::cout << " pubrel received. packet_id: " << packet_id << std::endl;
157
+ std::cout << " [server] pubrel received. packet_id: " << packet_id << std::endl;
144
158
return true ;
145
159
});
146
160
ep.set_pubcomp_handler (
147
- [& ]
161
+ []
148
162
(packet_id_t packet_id){
149
- std::cout << " pubcomp received. packet_id: " << packet_id << std::endl;
163
+ std::cout << " [server] pubcomp received. packet_id: " << packet_id << std::endl;
150
164
return true ;
151
165
});
152
166
ep.set_publish_handler (
153
- [&]
167
+ [&subs ]
154
168
(bool is_dup,
155
169
MQTT_NS::qos qos_value,
156
170
bool is_retain,
157
171
MQTT_NS::optional<packet_id_t > packet_id,
158
172
MQTT_NS::buffer topic_name,
159
173
MQTT_NS::buffer contents){
160
- std::cout << " publish received."
174
+ std::cout << " [server] publish received."
161
175
<< " dup: " << std::boolalpha << is_dup
162
176
<< " qos: " << qos_value
163
177
<< " retain: " << std::boolalpha << is_retain << std::endl;
164
178
if (packet_id)
165
- std::cout << " packet_id: " << *packet_id << std::endl;
166
- std::cout << " topic_name: " << topic_name << std::endl;
167
- std::cout << " contents: " << contents << std::endl;
179
+ std::cout << " [server] packet_id: " << *packet_id << std::endl;
180
+ std::cout << " [server] topic_name: " << topic_name << std::endl;
181
+ std::cout << " [server] contents: " << contents << std::endl;
168
182
auto const & idx = subs.get <tag_topic>();
169
183
auto r = idx.equal_range (topic_name);
170
184
for (; r.first != r.second ; ++r.first ) {
@@ -179,32 +193,36 @@ int main(int argc, char** argv) {
179
193
return true ;
180
194
});
181
195
ep.set_subscribe_handler (
182
- [&]
196
+ [&subs, wp ]
183
197
(packet_id_t packet_id,
184
198
std::vector<std::tuple<MQTT_NS::buffer, MQTT_NS::subscribe_options>> entries) {
185
- std::cout << " subscribe received. packet_id: " << packet_id << std::endl;
199
+ std::cout << " [server] subscribe received. packet_id: " << packet_id << std::endl;
186
200
std::vector<MQTT_NS::suback_reason_code> res;
187
201
res.reserve (entries.size ());
202
+ auto sp = wp.lock ();
203
+ BOOST_ASSERT (sp);
188
204
for (auto const & e : entries) {
189
205
MQTT_NS::buffer topic = std::get<0 >(e);
190
206
MQTT_NS::qos qos_value = std::get<1 >(e).get_qos ();
191
- std::cout << " topic: " << topic << " qos: " << qos_value << std::endl;
207
+ std::cout << " [server] topic: " << topic << " qos: " << qos_value << std::endl;
192
208
res.emplace_back (static_cast <MQTT_NS::suback_reason_code>(qos_value));
193
- subs.emplace (std::move (topic), ep. shared_from_this () , qos_value);
209
+ subs.emplace (std::move (topic), sp , qos_value);
194
210
}
195
- ep. suback (packet_id, res);
211
+ sp-> suback (packet_id, res);
196
212
return true ;
197
213
}
198
214
);
199
215
ep.set_unsubscribe_handler (
200
- [&]
216
+ [&subs, wp ]
201
217
(packet_id_t packet_id,
202
218
std::vector<MQTT_NS::buffer> topics) {
203
- std::cout << " unsubscribe received. packet_id: " << packet_id << std::endl;
219
+ std::cout << " [server] unsubscribe received. packet_id: " << packet_id << std::endl;
204
220
for (auto const & topic : topics) {
205
221
subs.erase (topic);
206
222
}
207
- ep.unsuback (packet_id);
223
+ auto sp = wp.lock ();
224
+ BOOST_ASSERT (sp);
225
+ sp->unsuback (packet_id);
208
226
return true ;
209
227
}
210
228
);
0 commit comments