MQTT 서버에 연결하기 위해서 Android App에서 개발한 것을 정리할려고 한다.
MQTT 라이브러리
1. paho MQTT
paho MQTT는 예전에 개발된 라이브러리이고, 지금은 개발이 중지된 것처럼 보인다. 예전에 개발한 라이브러리이여서 깃 issue에서는 android 12는 동작하지 않는다고 한다. 나도 android 10에서 개발하니 broadcast에서 자꾸 에러가 발생한다. (해결 방법은 따로 코드 수정을 해서 받으면 된다)
2. hannesa2 MQTT
paho MQTT에서 버전을 올리고 broadcast에서 worker로 동작하게 바꾼 라이브러리이다. 단점은 라이브러리에 적용된 라이브러리를 사용하기 위해서 최소 sdkversion을 31로 맞춰야한다.
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 |