비비디바비비부
프로그래밍저장소
비비디바비비부
전체 방문자
오늘
어제
  • 프로그래밍 (72)
    • 안드로이드 (5)
      • 잡다한 지식 (40)
      • Compose (2)
      • Design (3)
      • Project (6)
    • 리액트 (4)
      • 프로젝트 (1)
      • 잡다한 지식 (1)
    • 알고리즘 (3)
      • 알고리즘 문제 (3)
    • AI (4)
      • 딥러닝 (4)
    • CS (2)
    • 잡동사니 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
비비디바비비부

프로그래밍저장소

안드로이드/잡다한 지식

[안드로이드] MQTT 라이브러리 정리

2023. 10. 26. 15:20

MQTT 서버에 연결하기 위해서 Android App에서 개발한 것을 정리할려고 한다.

MQTT 라이브러리

1. paho MQTT

paho MQTT는 예전에 개발된 라이브러리이고, 지금은 개발이 중지된 것처럼 보인다. 예전에 개발한 라이브러리이여서 깃 issue에서는 android 12는 동작하지 않는다고 한다. 나도 android 10에서 개발하니 broadcast에서 자꾸 에러가 발생한다. (해결 방법은 따로 코드 수정을 해서 받으면 된다)

 

GitHub - eclipse/paho.mqtt.android: MQTT Android

MQTT Android. Contribute to eclipse/paho.mqtt.android development by creating an account on GitHub.

github.com

2. hannesa2 MQTT 

paho MQTT에서 버전을 올리고 broadcast에서 worker로 동작하게 바꾼 라이브러리이다. 단점은 라이브러리에 적용된 라이브러리를 사용하기 위해서 최소 sdkversion을 31로 맞춰야한다.

 

GitHub - hannesa2/paho.mqtt.android: Kotlin MQTT client for Android

Kotlin MQTT client for Android . Contribute to hannesa2/paho.mqtt.android development by creating an account on GitHub.

github.com

 

1번 2번 모두 사용해봤는데, 자바를 사용하거나 sdkversion이 31미만이면 1번, sdkversion이 최신 버전으면 2번을 추천한다.

 

나는 2번 라이브러리에서 예전 버전(4.1)을 사용했고, 아래 코드를 이용했다.

 

코드

private void init() {
    mqttAndroidClient = new MqttAndroidClient(context, "ipAddress", MqttClient.generateClientId(), Ack.AUTO_ACK);
    mqttAndroidClient.setForegroundService(createNotification());
    setMqttListener();
}

MqttAndroidClient 중 MqttClient.generateClientId() 는 지금 시간(ms) 기반으로 아이디를 지정해준다. 만약 고정 값을 사용하는 경우, autoReconnect할 때 접속된 ClientId가 있는 경우가 존재해서,  연결 유실 (32109) - java.io.EOFException 에러가 발생한다.

  private void setMqttListener() {
        try {
            MqttConnectOptions options = setUpConnectionOptions();
            ...
        }
}
private static MqttConnectOptions setUpConnectionOptions() {
        MqttConnectOptions connOpts = new MqttConnectOptions();
        connOpts.setUserName("userName"); // 없는 경우 사용 x
        connOpts.setPassword("password".toCharArray()); // 없는 경우 사용 x
        connOpts.setCleanSession(true);
        connOpts.setAutomaticReconnect(true);
        return connOpts;
}

연결 이전에 connection 옵션을 사용하고싶은 경우 위의 코드를 참고하면 된다. AutoReconnect는 연결이 끊어진 경우 자동으로 다시 재연결을 시도한다.

        mqttAndroidClient.setCallback(new MqttCallbackExtended() {
                @Override
                public void connectComplete(boolean reconnect, String serverURI) {
                    Log.d("MQTT", "connect Complete isReconnect: " + reconnect + " serverURI: " + serverURI);
                    if (reconnect) {
                        Log.d("MQTT", "Subscribe");
                        mqttAndroidClient.subscribe("topic", 0/*qos*/);
                    }
                }

                @Override
                public void connectionLost(Throwable cause) {
                    Log.d("MQTT", "connectionLost: " + cause);
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    if (topic.equals("topic")) {
                        String msg = new String(message.getPayload());
                        Log.d("MQTT", "message: " + msg);
                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.d("MQTT", "deliveryComplete token: " + token);
                }
            });
            mqttAndroidClient.connect(options).setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Log.i("MQTT", "Token: onSuccess");
                    mqttAndroidClient.subscribe("topic", 0 /*qos*/);
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Log.i("MQTT", "Token: onFailure " + exception.toString()
                    );
                    try {
                        mqttAndroidClient.reconnect();
                    } catch (MqttException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }

위의 코드는 연결 전 연결 리스너를 만들어서, 연결이 정상 동작하는지 확인한다. 그 후 연결을 한 뒤 ActionCallback을 만들어서 토픽을 통해 메시지가 오면 msg를 파싱한 뒤 로그를 찍는 것으로 마무리 했다.

저작자표시 비영리 동일조건 (새창열림)

'안드로이드 > 잡다한 지식' 카테고리의 다른 글

[안드로이드] Rxjava + retrofit2 연결 도중 취소하기  (0) 2023.12.26
[안드로이드] 원격 터치 기능 정리  (0) 2023.11.06
[안드로이드] DroidKnight 2023  (0) 2023.08.16
[안드로이드] 안드로이드 14 베타 1 알아보기 - 1  (2) 2023.05.26
[안드로이드] WifiManager에서 Deprecated된 기능들  (0) 2023.05.22
    '안드로이드/잡다한 지식' 카테고리의 다른 글
    • [안드로이드] Rxjava + retrofit2 연결 도중 취소하기
    • [안드로이드] 원격 터치 기능 정리
    • [안드로이드] DroidKnight 2023
    • [안드로이드] 안드로이드 14 베타 1 알아보기 - 1
    비비디바비비부
    비비디바비비부
    안드로이드 기술 블로그, 코딩 공부, 프로그래머

    티스토리툴바