2016-06-21 1 views
2

자택 어플리케이션을위한 간단한 MQTT 클라이언트를 만들고 libmosquittopp (libmosquitto의 C++ 버전)를 사용하고 있습니다.
이 라이브러리에 대한 문서는별로 없지만 "MQTTWrapper"클래스의 코드를 만드는 데 도움이되는 두 개의 예제 (herehere)가 있습니다.libmosquittopp - loop_stop() 메소드에서 샘플 클라이언트가 멈 춥니 다

MQTTWrapper.h :

#pragma once 

#include <mosquittopp.h> 
#include <string> 

class MQTTWrapper : public mosqpp::mosquittopp 
{ 
public: 
    MQTTWrapper(const char* id, const char* host_, int port_); 
    virtual ~MQTTWrapper(); 

    void myPublish(std::string topic, std::string value); 
private: 
    void on_connect(int rc); 
    void on_publish(int mid); 

    std::string host; 
    int port; 
}; 

MQTTWrapper.cpp

#include "MQTTWrapper.h" 

#include <iostream> 

MQTTWrapper::MQTTWrapper(const char* id, const char* host_, int port_) : 
    mosquittopp(id), host(host_), port(port_) 
{ 
    mosqpp::lib_init(); 

    int keepalive = 10; 
    if (username_pw_set("sampleuser", "samplepass") != MOSQ_ERR_SUCCESS) { 
     std::cout << "setting passwd failed" << std::endl; 
    } 
    connect_async(host.c_str(), port, keepalive); 
    if (loop_start() != MOSQ_ERR_SUCCESS) { 
     std::cout << "loop_start failed" << std::endl; 
    } 
} 

MQTTWrapper::~MQTTWrapper() 
{ 
    std::cout << "1" << std::endl; 
    if (loop_stop() != MOSQ_ERR_SUCCESS) { 
     std::cout << "loop_stop failed" << std::endl; 
    } 
    std::cout << "2" << std::endl; 
    mosqpp::lib_cleanup(); 
    std::cout << "3" << std::endl; 
} 

void MQTTWrapper::on_connect(int rc) 
{ 
    std::cout << "Connected with code " << rc << "." << std::endl; 
} 

void MQTTWrapper::myPublish(std::string topic, std::string value) { 
    int ret = publish(NULL, topic.c_str(), value.size(), value.c_str(), 1, false); 
    if (ret != MOSQ_ERR_SUCCESS) { 
     std::cout << "Sending failed." << std::endl; 
    } 
} 

void MQTTWrapper::on_publish(int mid) { 
    std::cout << "Published message with id: " << mid << std::endl; 
} 

내 주요() : 너무 많은에 대한

#include <iostream> 
#include <string> 
#include "MQTTWrapper.h" 

int main(int argc, char *argv[]) 
{ 
    MQTTWrapper* mqtt; 
    mqtt = new MQTTWrapper("Lewiatan IoT", "my.cloudmqtt.host", 12345); 

    std::string value("Test123"); 
    mqtt->myPublish("sensors/temp", value); 

    std::cout << "about to delete mqtt" << std::endl; 
    delete mqtt; 
    std::cout << "mqtt deleted" << std::endl; 
    return 0; 
} 

죄송합니다 여기

내 코드입니다 암호.

문제점을 컴파일하고 실행할 때 - loop_stop() 메소드의 MQTTWrapper 소멸자에서 응용 프로그램이 무한대로 멈춘다. (단지 9 분을 기다렸다.)
libmosquittopp 1.4.8 (debian 패키지)으로 테스트 한 다음 버전을 제거한 후 버전 번호 1.4.9 (github).

loop_start()loop_stop(bool force=false)은 메시징을 처리하는 별도의 스레드를 시작/중지해야합니다.

강제 중지 (loop_stop(true))로 테스트했지만 내 애플리케이션이 중지되고 데이터를 게시하지 않습니다. 반면에 loop_stop()은 데이터를 게시하지만 중지됩니다.

콘솔 출력 (make && ./executable) :

g++ -c MQTTWrapper.cpp 
g++ -c main.cpp 
g++ -o executable main.o MQTTWrapper.o -lmosquittopp 
about to delete mqtt 
1 
Connected with code 0. 
Published message with id: 1 
(here it hangs infinitely...) 

내 질문 :
loop_stop() 중단하고 어떻게 문제를 해결하려면?

(감사 모든 문서/튜토리얼/예)

답변

2

loop_stop() 전에 disconnect()를 호출하십시오. 당신은 또한 당신이 효과적으로을하고있는 것을 명심해야한다 : 클라이언트도 연결할 수있는 기회가 없었 겠지만,도 중지하도록 지시하기 전에 스레드가 실제로 시작

connect_async(); 
loop_start(); 
loop_stop(); 

.

그것은 콜백에서 작업을 실행 고려 가치 : 나는 on_publish`에()``분리를 추가 할 때 그것은 일

on_connect -> call publish 
on_publish -> call disconnect 
+0

()'. 고맙습니다. 콜백을 사용하여이 "작업 방법"에 대해 좀 더 자세히 설명해 주시겠습니까? 내 말은 - 데이터를 게시 할 때마다 다시 연결해야한다고 제안합니까? on_publish보다 disconnect()를 호출하는 것이 더 좋습니다 ... – lewiatan

+0

제시된 코드에서 메시지가 게시 된 후 연결하고 게시하려는 것처럼 보입니다. 나는 그 유스 케이스를 다루고 있었다. 계속해서 게시하려면 on_publish에서 연결을 끊는 것이 좋지 않을 수 있습니다. – ralight

+0

@lewiatan 나는 이것이 당신의 질문에 정말로 답하지 않는다고 느낍니다. 이것은 단지 멈춤 갭의 예일뿐입니다.모든 mosquitto 라이브러리 c/C++ 예제는 사용자가 이미 응답 한 것처럼 공평하지 않은 게시 후에 disconnect() 할 것을 기대합니다. 열어 놓은 채로있을 수 있습니다. – Kiran

관련 문제