ํ๋ก ํธ์์ ํน์ api๋ฅผ ํธ์ถํ๋ฉด ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ mqtt๋ฅผ ์ฌ์ฉํด์ ์๋์ฐ PC๋ ํค์ค์คํฌ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผ ํ๋ค. ์์ ์์ ๋ฐ์ดํฐ ์๊ณ , ์ด์ ์ ๋น์ทํ ํ๋ก์ ํธ์์ mosquitto๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํ ๋ ํผ๋ฐ์ค๊ฐ ์์ด MQTT๋ก ์ด๋ฅผ ๊ตฌํํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ Spring Boot ์น ์๋ฒ๋ publisher๋ผ๊ณ ํ ์ ์๊ณ , ์๋์ฐ PC๋ subscriber, mosquitto๋ broker ์ญํ ์ ํ๋ค
MQTT ํน์ง
- ๊ฒฝ๋ ํ๋กํ ์ฝ
- ์ต์ํ ๋ ํค๋
- 2๋ฐ์ดํธ ์ ๋์ ์ ์ ์ฉ๋ ๋ฉ์ธ์ง -> ์ ํ๋ ๋์ญํญ ํ๊ฒฝ์์๋ ์ฌ์ฉ ๊ฐ๋ฅ
- Publish/Subscribe ๋ชจ๋ธ
- Publisher (๋ฐํ ์ฃผ์ฒด) <-> Broker (์ค๊ฐ์๋ฒ) <-> Subscriber (๊ตฌ๋ ์ฃผ์ฒด)
- Publisher๋ ํน์ topic์ ๋ฉ์์ง๋ฅผ ๋ฐํํจ
- Subscriber๋ ์ํ๋ ์ฃผ์ ์ ๋ํด ๊ตฌ๋ ์ ์์ฒญ
- Broker๋ ํด๋น topic์ ๋ฉ์ธ์ง๊ฐ ๋ฐํ๋๋ฉด ๊ตฌ๋ ์์๊ฒ ์ ๋ฌ
- Publisher์ Subscriber๋ ์๋ก ๋ชฐ๋ผ๋ ๋๋ค
QoS (Quality of Service) Level
mqtt ํ๋กํ ์ฝ ๋ฟ๋ง ์๋๋ผ ๋ค์ํ ๋คํธ์ํฌ ๋ฐ ํต์ ์์ญ์์ ์ฌ์ฉ๋๋ ์ฉ์ด๋ก์ ์์ธํ ์ค๋ช ๊ณผ ์ฌ์ง์ ์๋ ์ปค๋ฎค๋ํฐ ์ฌ์ดํธ์์ ํ์ธ ๊ฐ๋ฅํ๋ค.
QoS 0
- ๋ฉ์ธ์ง๋ ์ต๋ ํ๋ฒ ์ ์กํ๋ฉฐ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ์ด ๋์๋์ง ์ฌ๋ถ๋ ํ์ธํ์ง ์์
- ๊ฐ์ฅ ๋ฎ์ ์์ค์ ๋ณด์ฅ ์๋น์ค
- ์๋๊ฐ ๋น ๋ฅด๋ค
- find and forget์ด๋ผ๊ณ ํ๋๋ฐ ๊ทธ ์ด์ ๋ ํ์ ์กฐ์น๋ ํ์ธ ์์ด ๋ฉ์ธ์ง๊ฐ ์ ์ก๋๋ ๊ธฐ๋ณธ TCP ํ๋กํ ์ฝ๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ
Qos 1
- ์ค๊ฐ ์์ค์ ์๋น์ค
- ์ ์ด๋ ํ๋ฒ ์ด์ ํด๋ผ์ด์ธํธ ์ธก์ผ๋ก ์ ๋ฌ๋๋๋ก ๋ณด์ฅ
- ์ ๋ฌ ์ฌ๋ถ๋ฅผ ํ์ธํด์ ๋ฉ์ธ์ง๊ฐ ์ ์์ ์ผ๋ก ์ ๋ฌ๋์ง ๋ชปํ๋ฉด ๋ฉ์ธ์ง๋ฅผ ๋ค์ ๋ณด๋ด๊ธฐ ์ํด ์๋ํ๋ค
- ๋ฉ์ธ์ง๋ ์ค๋ณต๋์ด ๋ณด๋ด์ง ์ ์์ผ๋ฉฐ ํ ๋ฒ๋ง ๋์ฐฉํ๋ค๋ ๋ณด์ฅ์ ์๋ค
- ๊ณผ์
- QoS 1๋ก ๋ฉ์ธ์ง๊ฐ published
- Publisher๋ ์์ ์๋ก ๋ถํฐ PUBACK ํจํท์ ์์ ํ ๋ ๊น์ง ๋ฉ์์ง์ ์ฌ๋ณธ์ ๋ณด๊ด
- Publisher๊ฐ ๋ง์ฝ ์ ์ ํ ์๊ฐ ๋ด์ PUBACK ํจํท์ ์์ ํ์ง ๋ชปํ๋ฉด ๋ฉ์ธ์ง๋ฅผ ์ฌ์ ์กํ๋ค
- ๋ฉ์์ง๋ฅผ ์ ์ก๋ฐ์ ์์ ์์ธ MQTT ๋ธ๋ก์ปค๋ ๋ชจ๋ ๊ตฌ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ๋ฐฐํฌ
- ๋ธ๋ก์ปค๋ ๋ฉ์ธ์ง ์์ ํ์ธ์ ์ํด Publisher์๊ฒ PUBACK ํจํท์ผ๋ก ์๋ต
QoS 2
- ๊ฐ์ฅ ๋์ ์์ค์ ๋ณด์ฅ ์๋น์ค
- ๊ฐ ๋ฉ์ธ์ง๊ฐ ์๋ํ ํด๋ผ์ด์ธํธ์๊ฒ ํ ๋ฒ๋ง ์ ํํ ์์ ๋๋๋ก ํจ
- ๋ฐ์ ์์ ์์ ์(๋ธ๋ก์ปค)๊ฐ์ 4๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋ ํธ๋์ธ์ดํฌ๋ฅผ ์ฌ์ฉํ๋ค.
- ์ ํํ ๋ฉ์ธ์ง๋ฅผ ์์ ํ๊ธฐ ์ํ ๊ณผ์ ๋๋ฌธ์ ์๋๊ฐ ๋ค๋ฅธ ๋ ๋ฒจ์ ๋นํด ๋๋ฆฌ๋ค
- ๊ณผ์
- broker๊ฐ publisher๋ก ๋ถํฐ PUBLISH ํจํท์ ๋ฐ๋๋ค
- broker๋ ๊ฒ์ ๋ฉ์ธ์ง๋ฅผ ์ฒ๋ฆฌํ๊ณ publisher์๊ฒ ๊ฒ์ ํจํท์ ์น์ธํ๋ PUBREC ํจํท์ผ๋ก ์๋ตํ๋ค.
- publisher๊ฐ broker๋ก ๋ถํฐ PUBREC ํจํท์ ๋ฐ์ง ๋ชปํ๋ฉด ์์ ์๊ฐ ํ์ธ์ ๋ฐ์ ๋๊น์ง DUP ํ๋๊ทธ๊ฐ ํฌํจ๋ PUBLISH ํจํท์ ์ฌ์ ์กํ๋ค
- publisher๋ broker๋ก ๋ถํฐ PUBREC ํจํท์ ๋ฐ์ผ๋ฉด publisher๋ ์ด๊ธฐ PUBLISHํจํท์ ์์ ํ๊ฒ ์ญ์ ํ๋ค
- publisher๋ brocker๋ก ๋ถํฐ PUBRECํจํท์ ๋ฐ์ ์ ์ฅํ๊ณ PUBREL ํจํท์ผ๋ก ์๋ตํ๋ค
- broker๋ PUBREL์ ๋ฐ์ผ๋ฉด ์ ์ฅ๋ ๋ชจ๋ ์ํ๋ฅผ ์ญ์ ํ๊ณ PUBCOMP ํจํท ์๋ต์ ๋ณด๋ธ๋ค
ํ ํฝ์ด๋
- MQTT ๋ฉ์ธ์ง๊ฐ ์ ๋ฌ๋๋ ๊ฒฝ๋ก
- home/factory1/temperature ์ ๊ฐ์ ํ์์ ๊ณ์ธต ๊ตฌ์กฐ์ด๋ค
- ๋ฉ์ธ์ง๋ฅผ ์ด๋ค ์ฉ๋๋ก ์ฌ์ฉํ ์ง์ ๋ฐ๋ผ ๋ถ๋ฅํด์ฃผ๋ ์ญํ
- ํด๋ผ์ด์ธํธ๋ ํน์ ํ ํฝ์ ๊ตฌ๋ ํ๊ณ ํด๋น ํ ํฝ์์ ๋ฐํ๋๋ ๋ฉ์ธ์ง๋ง ์์ ํ๋ค
=> ๋ฉ์์ง๋ฅผ ํน์ ์ฃผ์ ๋ ๋ฒ์ฃผ๋ก ๊ตฌ๋ถํ๋ ์ฃผ์ ์ญํ
ํ์ด๋ก๋
- ๋ฉ์์ง์ ์ค์ ๋ด์ฉ
- ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ๋ถ๋ถ
- home/factory1/temperature ํ ํฝ์ {"temperature": 30.1} ๊ณผ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ์ด๋ก๋์ ํฌํจ์ํฌ ์ ์์
- ํน์ ํ ํฝ์์ ๋ฐํ๋ ๋ฉ์์ง๊ฐ ์ด๋ค ์ ๋ณด๋ฅผ ํฌํจํ๋์ง ๊ฒฐ์
=> MQTT ๋ฉ์์ง๊ฐ ์ ๋ฌํ๊ณ ์ ํ๋ ์ค์ ๋ฐ์ดํฐ์ ํด๋นํจ
ํด๋ผ์ด์ธํธ ID
- ๊ณ ์ ID๋ฅผ ์ค์ ํด์ผ ํ๋ค
- ์ค๋ณต๋ ํด๋ผ์ด์ธํธ๋ id ์ฐ๊ฒฐ ์ถฉ๋์ ์ผ์ผ์ผ ๋์ค์ ์ ์ํ๋ client๋ disconnect ๋ ์ ์๋ค
์ฃผ์ MQTT
- Mosquitto
- EMQX
- RabbitMQ
๋ฑ๋ฑ
Spring Boot ๊ตฌํ
์์กด์ฑ ์ถ๊ฐ
dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
}
MQTT Configuration ์ค์
@Configuration
public class MqttConfig {
@Value("${mqtt.server}")
private String BROKER_URL;
@Value("${mqtt.client-id}")
private String CLIENT_ID;
@Value("${mqtt.user}")
private String userName;
@Value("${mqtt.password}")
private String password;
@Bean
public MqttClient mqttClient() throws MqttException {
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setKeepAliveInterval(30);
options.setConnectionTimeout(10);
options.setUserName(userName);
options.setPassword(password.toCharArray());
MqttClient client = new MqttClient(BROKER_URL, CLIENT_ID, new MemoryPersistence());
client.connect(options);
client.setCallback(new MqttCallback());
return client;
}
}
- ์ฌ๊ธฐ์ ๋งํ๋ client๋ MQTT server์ ์ ์ํ ํด๋ผ์ด์ธํธ๋ฅผ ์๋ฏธ (spring boot ์น ์๋ฒ)
- username๊ณผ password๊ฐ ์๋ ๊ฒฝ์ฐ MqttConnectOptions์ ์ถ๊ฐํด ์ค์ผ ํ๋ค.
MqttCallback
@Configuration
public class MqttConfig {
@Value("${mqtt.server}")
private String BROKER_URL;
@Value("${mqtt.client-id}")
private String CLIENT_ID;
@Value("${mqtt.user}")
private String userName;
@Value("${mqtt.password}")
private String password;
@Bean
public MqttClient mqttClient() throws MqttException {
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setKeepAliveInterval(30);
options.setConnectionTimeout(10);
options.setUserName(userName);
options.setPassword(password.toCharArray());
MqttClient client = new MqttClient(BROKER_URL, CLIENT_ID, new MemoryPersistence());
client.connect(options);
client.setCallback(new MqttCallback());
return client;
}
}
MqttPublisherService
@Slf4j
@Service
@RequiredArgsConstructor
public class MqttPublisherService {
private final MqttClient mqttClient;
@Value("${mqtt.qos}")
private int qos;
public void publish(String topic, String payload) throws MqttException {
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(qos);
mqttClient.publish(topic, message);
log.info("MQTT message published to topic {} :{}", topic, payload);
}
}
- ํ์ฌ client์ธ spring boot ์น ์๋ฒ๋ publisher๋ก์ ๋ฉ์ธ์ง๋ฅผ brocker server์ publishํ๋ค
mqttPublisherService.publish(MQTT_TOPIC, ttMsg.toString());
- ์ค์ ์ฌ์ฉ์ ์ด๋ ๊ฒ ์์ฑ๋ ์ ์๋ค
๊ตฌ๋ ํ์ธ ํ๊ธฐ & MQTT Explorer
- ์ ์ฌ์ดํธ์์ MQTT Explorer๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ mqtt ์๋ฒ์ publish ๋๋ ํ์ด๋ก๋์ ํ ํฝ์ ํ์ธํ ์ ์๋ค
sudo apt update
sudo apt install mosquitto-clients
mosquitto_sub -h {mqtt ip} -p {port} -t {topic}
- MQTT Explorer๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๊ฐ๋จํ๊ฒ ๋ก์ปฌ์์ ํ์ธํ ์ ์๋ ๋ฐฉ๋ฒ
- broker ์๋ฒ์ ํด๋น topic์ subscribeํ๋ค
'BE > ๐ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot] Custom Validation annotation (0) | 2024.11.10 |
---|---|
[Spring Boot] RestControllerAdvice๋ก Validation Exception ํธ๋ค๋งํ๊ธฐ (1) | 2024.11.09 |
[Spring Boot] Validation์ ๋ฐ์ํ ์ ์๋ ์๋ฌ ์์๋ณด๊ธฐ (0) | 2024.11.08 |
[Validation] spring boot validation ์ฌ์ฉ๋ฒ๊ณผ ์ข ๋ฅ (0) | 2024.11.07 |
[Spring Boot] Controller์ RestController ์ฐจ์ด์ ResponseBody (2) | 2024.09.22 |
๋๊ธ