MQTT 안드로이드 코틀린 클라이언트 + 서버 만들기
MQTT란?
MQTT(Message Queueing Telemetry Transport)는 2016년 국제 표준화된 발행(Publish)-구독(Subscribe) 기반의 메시지 송수신 프로토콜로 최소한의 전력과 패킷으로 통신합니다.
TCP/IP 프로토콜 위에서 동작하지만 가벼우면서도 많은 통신 제약을 해결할 수 있기에 모바일과 IoT 같은 환경에서 어울려 사용하기 좋습니다.
MQTT 구조도
또한 Topic 기반으로 발행/구독을 하기에 자신이 원하는 Topic을 Brocker을 통해 구독(Subscribe)하면 해당 Topic으로 발행(Publish)되는 메시지를 받을 수 있습니다.
이러한 아키텍처 덕에 IoT에서도 강한 이점을 보이며, Topic 분류 기준에 따라 같은 기능이라도 여러 방식으로 디자인을 할 수 있습니다.
예시를 들어볼까요? 팡무의 집에 거실, 침실, 화장실이 있고 이에 각각의 방에 IoT를 설치하였다고 가정하여 디자인을 하면 아래와 같은 구조들을 지닐 수 있게 됩니다.
방을 기준으로 분류
분류의 기준을 방이으로 잡게 되면, 각 방에 존재하는 각 장치(센서)를 해당 방의 하위 Topic으로 잡습니다.
장치를 기준으로 분류
반대로 장치(센서)가 분류의 기준이 된다면 방을 하위 Topic으로 잡습니다.
QoS란?
QoS(Quality of Service)를 통해 서비스 품질을 3단계를 통해 지정할 수 있습니다.
- 0: 메시지를 한 번만 전달합니다.
- At most once
- Fire-and-forget 패턴으로 수신 여부에 대한 체크를 하지 않기에 수신자는 해당 메시지를 받지 못할 수 있습니다.
- 1: 메시지를 한 번 이상 전달합니다.
- At least once
- 핸드쉐이킹 과정을 추적하지 않기에 수신자는 중복 수신의 가능성이 있습니다.
- 2: 메시지를 핸드쉐이킹으로 한 번만 전달합니다.
- Exactly once
- 핸드쉐이킹 모든 과정(발신자/수신자)을 2단계로 체크하기에 송신자는 수신자가 메시지를 받지 못하였더라도 중복으로 송신하지는 않습니다.
시작해봅시다.
MQTT에 대한 기본적인 지식을 습득하셨다면 이제 실제로 사용할 수 있도록 서버/클라이언트 설정을 해봅시다.
MQTT for Server
MQTT를 사용하기 위해서는 기본적으로 Brocker가 존재해야합니다. (MQTT 구조도 사진 참고)
mosquitto에서 제공하는 기능이 쉽고 강력하기에 타이핑 몇 번만 하시면 브로커를 구축할 수 있습니다.
설명은 우분투 기준으로 하지만, Mac의 경우 HomeBrew를 통해 똑같이 구축하실 수 있습니다.
브로커
패키지 설치
우선 apt-get을 통해 mosquitto 패키지를 설치합니다.
$sudo apt-get install mosquitto
브로커 시작
설치가 완료되셨나요? 그러면 실행하시면 완료입니다.
$mosquitto
엥 이게 끝인가요
네 그렇습니다. 끝 입니다.
정상적으로 완료되었는지 클라이언트로 테스트를 하시고 싶으시다면 아래의 과정을 추가로 따라하시면 됩니다.
클라이언트
패키지 설치
마찬가지로 apt-get을 통해 mosquitto-clients 패키지를 설치합니다.
$sudo apt-get install mosquitto-clients
구독자(Subscriber)
메시지를 받기 위해서는 Subscriber(구독자)가 Subscribe(구독)을 하고 있어야합니다.
이를 위해 아래의 명령어를 통해 간단하게 Subscribe을 시작할 수 있습니다.
기본 포트는 1883이며, 지정한 서버(SERVER_IP)의 포트(PORT)에 있는 토픽(TOPIC)으로 연결됩니다.
$mosquitto_sub -h {SERVER_IP} -p {PORT} -t {TOPIC}
위의 명령어를 실행하더라도 아직 Publish되고 있는 메시지가 없기에 아무런 변화가 없는 것 처럼 보입니다.
그렇기에 Publish를 할 수 있도록 명령어를 날려봅시다.
발행자(Publisher)
아래의 명령어를 실행하면 지정한 토픽으로 메시지를 전송하게 됩니다.
$mosquitto_pub -h {SERVER_IP} -p {PORT} -t {TOPIC} -m {MESSAGE}
결과
위의 과정을 정상적으로 따라하셨다면 아래와 같이 메시지를 수신받게 됩니다.
MQTT for Android
기본적인 설명은 위에서 모두 하였기에 거두절미하고 안드로이드에서 사용해보도록 하겠습니다.
우선 MQTT를 사용할 수 있도록 아래의 라이브러리를 디펜던시 추가합니다.
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
그런 다음 MqttClient를 만듭니다. 이때 포트를 잘못 입력하면 당연히 연결 오류가 발생합니다.
val client = MqttClient("tcp://아이피주소:포트", MqttClient.generateClientId(), null)
MqttClient를 만들었다면 연결을 합니다.
client.connect()
연결 후에는 Topic을 구독합니다.
client.subscribe("토픽 이름")
구독까지 완료하였다면 이제 메시지 송신/수신/연결 상태에 대한 정보를 받을 수 있도록 콜백을 설정합니다.
각 TODO에 원하시는 로직을 넣으시면 됩니다.
client.setCallback(object : MqttCallback {
override fun connectionLost(cause: Throwable?) {
TODO("연결 끊겼을 때")
}
override fun messageArrived(topic: String?, message: MqttMessage?) {
TODO("메시지를 수신받았을 때")
}
override fun deliveryComplete(token: IMqttDeliveryToken?) {
TODO("메시지를 전송하였을 때")
}
})
메시지를 발행(Publish)하고 싶으시다면 publish 함수를 통해 가능합니다.
client.publish("토픽 이름", MqttMessage("메시지 내용".toByteArray()))
추가로 연결/구독을 하였다면 잊지말고 해지 기능도 넣어주세요.
override fun onDestroy() {
client.unsubscribe("토픽 이름")
client.disconnect()
super.onDestroy()
}