Docker MQTT 통신 C++
이번에는 C++ 로 통신 구현!
1. 컨테이너 열 때 포트포워딩 필수! (이건 전 포스팅에 쓰여있음)
2. 파일 구성은 이런 식. 이게 뭐야! 싶겠지만 컨테이너 열어서 build 폴더 하나만 만드시고 아래 따라하면 됩니다.
3. 일단 통신이 되는 CPP 기본 소스! (main.cpp)
코드 설명은 안 할 거고 중요한 건 포트포워딩할 때 포트 번호, 현재 호스트 IP 주소, 토픽 이름입니다. 포트 번호는 컨테이너를 열었을 때 포워딩한 번호, IP 주소는 로컬, 토픽 이름은 나중에 MQTT를 연결할 때 사용하니 임의로 적으셔도 무방.
#include <mosquitto.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#define mqtt_host "127.0.0.1"
#define mqtt_port 1883
#define keep_alive 60
int main(int argc, char **argv)
{
mosquitto_lib_init();
struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);
if(mosq)
{
if(mosquitto_connect(mosq, mqtt_host, mqtt_port, keep_alive) != MOSQ_ERR_SUCCESS)
{
fprintf(stderr, "Unable to connect.\n");
return -1;
}
while(true){
const char *msg = "Hello, MQTT!";
int ret = mosquitto_publish(mosq, NULL, "cpp/test", strlen(msg), msg, 0, false);
if(ret != MOSQ_ERR_SUCCESS)
{
fprintf(stderr, "Failed to publish message: %s\n", mosquitto_strerror(ret));
}
else
{
printf("Message published successfully\n");
}
sleep(5);
}
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
}
else
{
fprintf(stderr, "Failed to create mosquitto instance.\n");
}
mosquitto_lib_cleanup();
return 0;
}
4. CMakeLists 파일 생성 (CMakeLists.txt)
그냥 복붙하되 project 이름은 바꿔줄 수 있습니다.
cmake_minimum_required(VERSION 3.0)
project(MosquittoClientExample)
find_package(PkgConfig REQUIRED)
pkg_search_module(MOSQUITTO REQUIRED libmosquitto)
add_executable(mqtt_client main.cpp)
target_link_libraries(mqtt_client ${MOSQUITTO_LIBRARIES})
target_include_directories(mqtt_client PUBLIC ${MOSQUITTO_INCLUDE_DIRS})
5. 그리고 cpp, cmakelists를 만들어 준 바로 그 경로에 build 파일 만드세요.
mkdir build
cd build
6. build
근데 이렇게 빌드하다가 막히는 사람 분명 있을 겁니다.
cmake ..
cmake --build .
그럼 아래 중에 골라서 해결하세요. 완전 친절하다. 인정~
# 1. 공통
sudo apt-get update
# 2. cmake 문제일 시
sudo apt-get install cmake
# 3. pkg-config 문제일 시
sudo apt-get install pkg-config
# 4. mosquitto-dev 문제일 시
sudo apt-get install libmosquitto-dev
# 4-1. 4번이 안 될 시
sudo apt-get update -y
sudo apt-get install -y libmosquitto-dev
7. mosquitto broker 실행
mosquitto -v
8. 코드 실행
위 7번을 실행했으면 console 창이 mosquitto log가 찍혀서 안 될 텐데 그땐 쿨하게 새 탭 열어서 docker 중복 접속으로 하세요. 백그라운드 실행하는 방법이 있으면 나도 알려주고. (귀찮으니까)
# 이건 cmake 이름을 바꾸면 달라질 수 있음
# ls 하여 실행 파일 이름 확인해서 실행하세요
./mqtt_client
9. subscribe 해서 확인
이건 전 포스팅처럼 MQTT Explorer를 이용해서 확인합니다. 똑같은 설정인데 캡쳐하기 귀찮으니까 설정 손댄 부분만 이야기하면
* Host = Docker 연 Linux PC의 IP (나는 192.168.40.128)
* Port = Container 열 때 포워딩한 Port (51005:1883이면 51005. 1883은 Publish할 때 씀. 나는 51005였음)
* ADVANCED 클릭하여 topic 추가 (Cpp 코드에 사용한 topic 넣으면 됨)
+ 추가
10. subscribe에서 access denied가 뜬다. 그러면 mosquitto -v 할 때 아래 뜨는 log에서 Starting in local only mode인지 아닌지 확인해야 된다. 이때 local mode로 돼 있으면 container 안에서만 통신이 되고 바깥으로는 통신이 안 된다. 접근도 안 되는 듯하다.
해결 방법은 docker 내부에 있는 mosquitto.conf 파일을 찾아 접근할 수 있도록 수정하는 것이다. 아래 명령어를 복사해 붙이면 된다.
find / -name mosquitto.conf 2>/dev/null
그러면 어디에 있는지 뜨기 때문에 cd를 통해 접근하고 수정하면 된다. 추가할 코드는 아래와 같다.
listener 1883 0.0.0.0
allow_anonymous true
추가했으면 저장. 저장한 다음에는 원래 사용했던 mosquitto -v가 아니라 다른 명령어를 통해서 실행한다.
mosquitto -c mosquitto.conf -v
이 명령어를 통해서 실행하지 않으면 local mode로 실행되고, mosquitto.conf 파일이 적용되지 않는 듯하다. 이 명령어를 통해 실행한 다음에 다시 mqtt publish를 시작하면 외부에서 접근이 가능하다.