提交 00fb7c60 authored 作者: blu's avatar blu

mqtt api: future style

上级 74dfdf95
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <thread> #include <thread>
#include <set> #include <set>
#include <map> #include <map>
#include <future>
extern "C" { extern "C" {
#include "MQTTAsync.h" #include "MQTTAsync.h"
...@@ -54,9 +55,11 @@ class MqttPub { ...@@ -54,9 +55,11 @@ class MqttPub {
if ((rc = MQTTAsync_sendMessage(client, topic.c_str(), &pubmsg, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_sendMessage(client, topic.c_str(), &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{ {
printf("Failed to start sendMessage %d\n", rc); string msg = fmt::format("Failed to start sendMessage: {}", MQTTAsync_strerror(rc));
exit(EXIT_FAILURE); spdlog::info(msg);
throw msg;
} }
return 0;
} }
~MqttPub(){ ~MqttPub(){
...@@ -81,7 +84,8 @@ class MqttHelper { ...@@ -81,7 +84,8 @@ class MqttHelper {
Destroyed Destroyed
}; };
State state = State::None; // 0: initial ; 1: ready; 2: disconnected; 3: destroyed /// State state = State::None; // 0: initial ; 1: ready; 2: disconnected; 3: destroyed
promise<State> state;
MqttHelper(string mqtt_addr, string id, int kai = 20, int cs = 1): mqtt_addr(mqtt_addr){ MqttHelper(string mqtt_addr, string id, int kai = 20, int cs = 1): mqtt_addr(mqtt_addr){
// make connection, throw excpetions // make connection, throw excpetions
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
...@@ -112,11 +116,20 @@ class MqttHelper { ...@@ -112,11 +116,20 @@ class MqttHelper {
spdlog::error(msg); spdlog::error(msg);
throw StrException(msg); throw StrException(msg);
} }
State st = state.get_future().get();
if(st != State::Ready){
spdlog::error("failed to initilaze mqtt");
}else{
spdlog::info("initialze mqtt successfully");
}
state = promise<State>();
} }
// can be called only state // can be called only state
int subscribe(string topic, on_msg_fun_ptr_t on_msg/*, on_res_fun_ptr_t on_success = nullptr, on_res_fun_ptr_t on_failure = nullptr*/){ int subscribe(string topic, on_msg_fun_ptr_t on_msg/*, on_res_fun_ptr_t on_success = nullptr, on_res_fun_ptr_t on_failure = nullptr*/){
assert(state != State::None); // assert(state != State::None);
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
int rc; int rc;
// if(topics.contains(topic)){ // if(topics.contains(topic)){
...@@ -137,6 +150,7 @@ class MqttHelper { ...@@ -137,6 +150,7 @@ class MqttHelper {
}else{ }else{
spdlog::info("subscribe {} success", topic); spdlog::info("subscribe {} success", topic);
} }
return 0;
} }
MqttPub operator[](string topic){ MqttPub operator[](string topic){
...@@ -150,6 +164,7 @@ class MqttHelper { ...@@ -150,6 +164,7 @@ class MqttHelper {
}else{ }else{
spdlog::warn("no handler installed for topic: {}", topic); spdlog::warn("no handler installed for topic: {}", topic);
} }
return 0;
} }
...@@ -159,11 +174,13 @@ class MqttHelper { ...@@ -159,11 +174,13 @@ class MqttHelper {
opts.onSuccess = on_disconn; opts.onSuccess = on_disconn;
opts.context = this; opts.context = this;
state = promise<State>();
if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
{ {
spdlog::info("Failed to start disconnect: {}", MQTTAsync_strerror(rc)); spdlog::info("Failed to start disconnect: {}", MQTTAsync_strerror(rc));
} }
state.get_future().get();
MQTTAsync_destroy(&client); MQTTAsync_destroy(&client);
} }
...@@ -175,16 +192,16 @@ void on_connlost(void *context, char *cause) ...@@ -175,16 +192,16 @@ void on_connlost(void *context, char *cause)
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc; int rc;
printf("\nConnection lost\n"); spdlog::error("mqtt connection lost: {}", cause? cause: "unkown reason");
if (cause)
printf(" cause: %s\n", cause);
printf("Reconnecting\n"); spdlog::info("reconnecting");
conn_opts.keepAliveInterval = 20; conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1; conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(self->client, &conn_opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_connect(self->client, &conn_opts)) != MQTTASYNC_SUCCESS)
{ {
printf("Failed to start connect, return code %d\n", rc); string msg = fmt::format("Failed to start connect:", MQTTAsync_strerror(rc));
spdlog::error(msg);
//self->state.set_exception(StrException(msg));
} }
} }
...@@ -194,17 +211,13 @@ int on_msgarrvd(void *context, char *topic, int topicLen, MQTTAsync_message *mes ...@@ -194,17 +211,13 @@ int on_msgarrvd(void *context, char *topic, int topicLen, MQTTAsync_message *mes
char* payloadptr; char* payloadptr;
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
printf("Message arrived\n"); spdlog::debug("new messge at {}:", topic);
printf(" topic: %s\n", topic); string msg;
printf(" message: "); msg.resize(message->payloadlen + 1);
payloadptr = (char *)message->payload; payloadptr = (char *)message->payload;
for(i=0; i<message->payloadlen; i++) memcpy(msg.data(), message->payload, message->payloadlen);
{ msg.data()[message->payloadlen] = 0;
putchar(*payloadptr++); spdlog::debug("\t{}", msg);
}
putchar('\n');
(*self)(string(topic), message->payload, message->payloadlen); (*self)(string(topic), message->payload, message->payloadlen);
MQTTAsync_freeMessage(&message); MQTTAsync_freeMessage(&message);
MQTTAsync_free(topic); MQTTAsync_free(topic);
...@@ -215,40 +228,50 @@ int on_msgarrvd(void *context, char *topic, int topicLen, MQTTAsync_message *mes ...@@ -215,40 +228,50 @@ int on_msgarrvd(void *context, char *topic, int topicLen, MQTTAsync_message *mes
void on_disconn(void* context, MQTTAsync_successData* response) void on_disconn(void* context, MQTTAsync_successData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
self->state = MqttHelper::State::Disconnected; // self->state = MqttHelper::State::Disconnected;
printf("Successful disconnection\n"); // if(self->state.get_future().valid()){
// self->state = std::promise<MqttHelper::State>();
// }
self->state.set_value(MqttHelper::State::Disconnected);
spdlog::info("successful disconnection");
} }
void on_subscribed(void* context, MQTTAsync_successData* response) void on_subscribed(void* context, MQTTAsync_successData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
printf("Subscribe succeeded\n"); spdlog::info("Subscribe succeeded");
} }
void on_subscribed_fail(void* context, MQTTAsync_failureData* response) void on_subscribed_fail(void* context, MQTTAsync_failureData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
spdlog::error("Subscribe failed: {}", MQTTAsync_strerror(response ? response->code : 0)); string msg = fmt::format("Subscribe failed: {}", MQTTAsync_strerror(response ? response->code : 0));
spdlog::error(msg);
//self->state.set_exception(StrException(msg));
} }
void on_conn_fail(void* context, MQTTAsync_failureData* response) void on_conn_fail(void* context, MQTTAsync_failureData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
printf("Connect failed, rc %d\n", response ? response->code : 0); string msg = fmt::format("Connect failed: {}", MQTTAsync_strerror(response ? response->code : 0));
spdlog::info(msg);
//self->state.set_exception(StrException(msg));
} }
void on_sent(void* context, MQTTAsync_successData* response) void on_sent(void* context, MQTTAsync_successData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
printf("Message with token value %d delivery confirmed\n", response->token); spdlog::info("Message with token value {} delivery confirmed", response->token);
} }
void on_connected(void* context, MQTTAsync_successData* response) void on_connected(void* context, MQTTAsync_successData* response)
{ {
MqttHelper *self = (MqttHelper *) context; MqttHelper *self = (MqttHelper *) context;
self->state = MqttHelper::State::Ready; // if(self->state.get_future().valid()){
// self->state = std::promise<MqttHelper::State>();
// }
self->state.set_value(MqttHelper::State::Ready);
spdlog::info("connected"); spdlog::info("connected");
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
...@@ -265,8 +288,7 @@ void on_connected(void* context, MQTTAsync_successData* response) ...@@ -265,8 +288,7 @@ void on_connected(void* context, MQTTAsync_successData* response)
if ((rc = MQTTAsync_subscribe(self->client, topic.c_str(), 1, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_subscribe(self->client, topic.c_str(), 1, &opts)) != MQTTASYNC_SUCCESS)
{ {
printf("Failed to start subscribe, return code %d\n", rc); spdlog::info("Failed to start subscribe: {}", MQTTAsync_strerror(rc));
exit(EXIT_FAILURE);
}else{ }else{
spdlog::info("successfully subscribed the test direct topic: {}", topic); spdlog::info("successfully subscribed the test direct topic: {}", topic);
} }
...@@ -278,21 +300,20 @@ void on_connected(void* context, MQTTAsync_successData* response) ...@@ -278,21 +300,20 @@ void on_connected(void* context, MQTTAsync_successData* response)
int main(){ int main(){
{ {
MqttHelper hlp("tcp://evcloud.ilabservice.cloud:1883", "testaabbc"); MqttHelper hlp("tcp://evcloud.ilabservice.cloud:1883", "testaabbc");
while(hlp.state == MqttHelper::State::None){ // while(hlp.state == MqttHelper::State::None){
spdlog::info("not state"); // spdlog::info("not state");
this_thread::sleep_for(chrono::milliseconds(200)); // this_thread::sleep_for(chrono::milliseconds(200));
} // }
hlp["hello"].pub("hello", 6, 1); hlp["hello"].pub("hello", 6, 1);
hlp.subscribe("bbbb", NULL); hlp.subscribe("bbbb", NULL);
this_thread::sleep_for(chrono::seconds(5)); this_thread::sleep_for(chrono::seconds(4));
} }
this_thread::sleep_for(chrono::seconds(5)); this_thread::sleep_for(chrono::seconds(3));
return 0; return 0;
} }
#endif #endif
#endif #endif
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论