Notice
Recent Posts
Recent Comments
Link
투케이2K
174. (TWOK/UTIL) [Web/JavaScript] paho-mqtt 라이브러리 및 aws4fetch 사용해 AWS IOT Core MQTT 구독 , 메시지 발생 수행 본문
투케이2K 유틸파일
174. (TWOK/UTIL) [Web/JavaScript] paho-mqtt 라이브러리 및 aws4fetch 사용해 AWS IOT Core MQTT 구독 , 메시지 발생 수행
투케이2K 2025. 11. 23. 18:51728x90
[설 명]
프로그램 : Web / JavaScript
설 명 : [Web/JavaScript] paho-mqtt 라이브러리 및 aws4fetch 사용해 AWS IOT Core MQTT 구독 , 메시지 발생 수행
[소스 코드]
-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------
- 개발 환경 : Web
- 개발 기술 : JavaScript (자바스크립트) / AWS / MQTT / paho-mqtt / aws4fetch
- 사전) MQTT (Message Queuing Telemetry Transport) 설명 :
>> MQTT 는 경량 메시지 프로토콜로, 주로 IoT(사물인터넷) 환경에서 사용됩니다
>> MQTT 목적 : 제한된 네트워크 환경(저속, 불안정)에서 효율적으로 메시지를 주고받기 위해 설계
>> MQTT 기반 : TCP/IP 위에서 동작
>> MQTT 패턴 : Publish/Subscribe 모델을 사용
- Publisher : 메시지를 발행하는 클라이언트
- Subscriber : 특정 주제(topic)를 구독하는 클라이언트
- Broker: 메시지를 중개하는 서버 (예: Mosquitto)
>> MQTT 주요 특징 :
- 경량성 : 헤더가 매우 작음(2바이트부터 시작)
- QoS (Quality of Service) :
$ QoS 0: 최대 한 번 전달(보장 없음)
$ QoS 1: 최소 한 번 전달(중복 가능)
$ QoS 2: 정확히 한 번 전달(가장 안전)
- 지속 연결 : KeepAlive로 연결 상태 유지
- Last Will and Testament (LWT) : 클라이언트 비정상 종료 시 브로커가 메시지 발행
- 토픽 기반 라우팅 : 계층적 구조(/home/temperature 등)
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
[소스 코드]
-----------------------------------------------------------------------------------------
<!DOCTYPE HTML>
<html lang="ko">
<head>
<title>javaScriptTest</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 반응형 구조 만들기 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<!-- 내부 CSS 스타일 지정 -->
<style>
html, body {
width: 100%;
height: 100%;
margin : 0 auto;
padding : 0;
border : none;
background-color: #666;
}
</style>
<!-- [CDN 주소 설정] : https://www.jsdelivr.com/package/npm/paho-mqtt -->
<script src="https://cdn.jsdelivr.net/npm/paho-mqtt@1.1.0/paho-mqtt.min.js"></script>
<!-- [자바스크립트 코드 지정] -->
<script type="module">
// --------------------------------------------------------------------------------------------------------------
// [모듈 import]
import aws4 from "https://esm.sh/aws4fetch@1.0.17";
const { AwsClient } = aws4;
// --------------------------------------------------------------------------------------------------------------
// [전역 변수 선언]
const endpoint = 'a1..pd9-ats.iot.ap-northeast-1.amazonaws.com'; // [AWS iot:Data-ATS 도메인]
const region = 'ap-northeast-1'; // [AWS 리전]
const accessKey = 'AK..7Q'; // [IAM 액세스 키]
const secretKey = 'Zz..xj'; // [IAM 시크릿 키]
var mqttClient = null;
var connectTimer = null;
// --------------------------------------------------------------------------------------------------------------
// [html 최초 로드 및 이벤트 상시 대기 실시]
window.onload = async function() {
console.log("");
console.log("=========================================");
console.log("[window onload] : [start]");
console.log("=========================================");
console.log("");
try {
// --------------------------------------
// AWS : SigV4 인증 URL 생성
// --------------------------------------
const aws = new AwsClient({
accessKeyId: accessKey,
secretAccessKey: secretKey,
service: "iotdevicegateway", // ✅ 중요!
region: region,
});
const url = `wss://${endpoint}/mqtt`; // [AWS iot:Data-ATS 도메인]
console.log("");
console.log("=========================================");
console.log("[window onload] : [aws.sign] : [request]");
console.log("---------------------------------------");
console.log("[url] : ", url);
console.log("=========================================");
console.log("");
// [SigV4 서명된 URL 생성]
const signed = await aws.sign(url, {
method: "GET",
signQuery: true // ✅ signQuery: true 옵션 추가
});
console.log("");
console.log("=========================================");
console.log("[window onload] : [aws.sign] : [reponse]");
console.log("---------------------------------------");
console.log("[signed all] : ", signed);
console.log("---------------------------------------");
console.log("[signed.url] : ", signed.url);
console.log("=========================================");
console.log("");
// --------------------------------------
// Call : Mqtt Connect
// --------------------------------------
//mqttConnect("broker.hivemq.com", 8000); // Default
mqttConnect(signed.url, 0); // AWS WebSocket : wss://<endpoint>/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[window onload] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
};
// [Create : Mqtt Object]
function mqttConnect(url, port) {
console.log("");
console.log("=========================================");
console.log("[mqttConnect] : [start]");
console.log("---------------------------------------");
console.log("[url] : ", url);
console.log("---------------------------------------");
console.log("[port] : ", port);
console.log("=========================================");
console.log("");
try {
// --------------------------------------
// Set : Client Id
// --------------------------------------
const clientId = "clientId-" + Math.random();
// --------------------------------------
// Set : Paho.Client
// --------------------------------------
if (port > 0){
mqttClient = new Paho.Client(url, port, "clientId-" + Math.random()); // Default
}
else { // ✅ port <= 0 : AWS 시도 처리
mqttClient = new Paho.Client(url, "clientId-" + Math.random()); // ✅ AWS WebSocket : wss:// 443 자동 할당
}
//mqttClient = new Paho.Client("broker.hivemq.com", 8000, "clientId-" + Math.random()); // Success Test
//mqttClient = new Paho.Client("tcp://broker.hivemq.com", 8000, "clientId-" + Math.random()); // Fail Test
//mqttClient = new Paho.Client("broker.hivemq.com", 1883, "clientId-" + Math.random()); // TimeOut Test
console.log("Client created : ", mqttClient);
// --------------------------------------
// Set : callback handlers
// --------------------------------------
mqttClient.onConnectionLost = onConnectionLost;
mqttClient.onMessageArrived = onMessageArrived;
// --------------------------------------
// Connect : mqttClient
// --------------------------------------
console.log("");
console.log("=========================================");
console.log("[Mqtt] : connect : start");
console.log("=========================================");
console.log("");
if (port > 0){
mqttClient.connect({onSuccess:onConnect}); // Default
}
else { // ✅ port <= 0 : AWS 시도 처리
mqttClient.connect({
useSSL: true, // ✅ SSL/TLS 사용 여부 : 반드시 true 설정
mqttVersion: 4, // MQTT 프로토콜 버전 (MQTT v3.1.1)
timeout: 20, // 연결 시도 타임아웃 (초) → 기본값은 30초
keepAliveInterval: 30, // ✅ Ping 주기 (초) → 기본값은 60초
cleanSession: true, // ✅ 이전 세션 구독 정보 삭제
/*
invocationContext: { // 연결 시 컨텍스트 객체 → 콜백에서 context로 접근 가능
clientId: "mqtt-client"
},
// */
onSuccess:onConnect, // 연결에 따른 콜백
onFailure: (err) => console.error("Connection failed : ", err) // 연결에 따른 에러 메시지
});
}
//mqttClient.connect({onSuccess:onConnect});
// --------------------------------------
// Connect : TimeOut Handler
// --------------------------------------
connectTimer = setTimeout(() => {
console.error("");
console.error("=========================================");
console.error("[Mqtt] : connect : TimeOut");
console.error("=========================================");
console.error("");
try {
if (mqttClient != null){
mqttClient.disconnect(); // connect clear >> onConnectionLost
mqttClient = null;
}
}
catch (exception) {
// disconnect Fail >> call onConnectionFail
try {
throw new Error("TimeOut Failed to Connection");
}
catch (error){
if (error.message.indexOf("Failed to") >= 0){
onConnectionFail(error);
}
}
}
}, 5000);
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[mqttConnect] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
if (exception.message.indexOf("Failed to") >= 0){
onConnectionFail(exception);
}
}
}
// [Connection : Callback Handler]
function onConnect() {
// --------------------------------------
// Check : Paho Client
// --------------------------------------
if (mqttClient == null){
return;
}
console.log("");
console.log("=========================================");
console.log("[Mqtt] : connect : onSuccess");
console.log("=========================================");
console.log("");
// --------------------------------------
// Clear : Connect TimeOut Timer
// --------------------------------------
if (connectTimer != null){
clearTimeout(connectTimer);
connectTimer = null;
}
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
//onSubscribe("/TWOK/2K"); // Default : Set Subscribe
//onPublish("/TWOK/2K", "Hello"); // Default : Send Publish
// ---------------------------------
onSubscribe("$aws/things/T_TWK_0000000001/shadow/name/common/update/#"); // Aws Named Shadow : Set Subscribe
const json = {
state: {
reported: {
command: "COMMON.COMMAND"
}
}
}
onPublish("$aws/things/T_TWK_0000000001/shadow/name/common/update", JSON.stringify(json)); // Aws Named Shadow : Send Publish
// ---------------------------------
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onConnect] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// [Connection : Callback Handler]
function onConnectionLost(responseObject) {
console.error("");
console.error("=========================================");
console.error("[Mqtt] : connect : onConnectionLost");
console.error("---------------------------------------");
console.error("[responseObject] : ", JSON.stringify(responseObject));
console.error("---------------------------------------");
console.error("[errorCode] : ", responseObject.errorCode);
console.error("---------------------------------------");
console.error("[errorMessage] : ", responseObject.errorMessage);
console.error("=========================================");
console.error("");
/*
-----------------------------------------
[errorCode] : 종류
-----------------------------------------
0 : 정상 종료 (예: 클라이언트에서 명시적으로 disconnect() 호출)
-----------------------------------------
1 : 소켓 오류 (네트워크 문제로 연결이 끊김)
-----------------------------------------
2 : 프로토콜 오류 (MQTT 프로토콜 위반)
-----------------------------------------
3 : 메시지 전송 오류 (메시지 처리 중 내부 오류)
-----------------------------------------
4 : KeepAlive 타임아웃 (브로커 응답 없음)
-----------------------------------------
5 : 내부 오류 (예: AMQJS0005E와 같은 내부 예외)
-----------------------------------------
// */
// --------------------------------------
// Clear : Connect TimeOut Timer
// --------------------------------------
if (connectTimer != null){
clearTimeout(connectTimer);
connectTimer = null;
}
// --------------------------------------
// Clear : Mqtt Object
// --------------------------------------
try {
if (mqttClient != null){
mqttClient.disconnect();
mqttClient = null;
}
}
catch (exception) { // disconnect error
console.error("[Mqtt] : onConnectionLost : disconnect : Exception : ", exception.message);
mqttClient = null;
}
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
var onConnectionLostReason = "";
if (responseObject.errorCode == 0){
onConnectionLostReason = String(responseObject.errorCode) + " : 정상 종료 (예: 클라이언트에서 명시적으로 disconnect() 호출)";
}
else if (responseObject.errorCode == 1){
onConnectionLostReason = String(responseObject.errorCode) + " : 소켓 오류 (네트워크 문제로 연결이 끊김)";
}
else if (responseObject.errorCode == 2){
onConnectionLostReason = String(responseObject.errorCode) + " : 프로토콜 오류 (MQTT 프로토콜 위반)";
}
else if (responseObject.errorCode == 3){
onConnectionLostReason = String(responseObject.errorCode) + " : 메시지 전송 오류 (메시지 처리 중 내부 오류)";
}
else if (responseObject.errorCode == 4){
onConnectionLostReason = String(responseObject.errorCode) + " : KeepAlive 타임아웃 (브로커 응답 없음)";
}
else if (responseObject.errorCode == 5){
onConnectionLostReason = String(responseObject.errorCode) + " : 내부 오류 (예: AMQJS0005E와 같은 내부 예외)";
}
else {
onConnectionLostReason = String(responseObject.errorCode) + " : ELSE";
}
console.error("");
console.error("=========================================");
console.error("[Mqtt] : onConnectionLostReason : ", onConnectionLostReason);
console.error("=========================================");
console.error("");
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onConnectionLost] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// [Connection : Callback Handler]
function onConnectionFail(error) {
console.error("");
console.error("=========================================");
console.error("[Mqtt] : connect : onConnectionFail");
console.error("---------------------------------------");
console.error("[errorName] : ", error.name);
console.error("---------------------------------------");
console.error("[errorMessage] : ", error.message);
console.error("=========================================");
console.error("");
// --------------------------------------
// Clear : Connect TimeOut Timer
// --------------------------------------
if (connectTimer != null){
clearTimeout(connectTimer);
connectTimer = null;
}
// --------------------------------------
// Clear : Mqtt Object
// --------------------------------------
try {
if (mqttClient != null){
mqttClient.disconnect();
mqttClient = null;
}
}
catch (exception) { // disconnect error
console.error("[Mqtt] : onConnectionFail : disconnect : Exception : ", exception.message);
mqttClient = null;
}
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onConnectionFail] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// [Topic : Subscribe]
function onSubscribe(topic) {
// --------------------------------------
// Check : Paho Client
// --------------------------------------
if (mqttClient == null){
return;
}
console.log("");
console.log("=========================================");
console.log("[Mqtt] : onSubscribe : Start");
console.log("---------------------------------------");
console.log("[topic] : ", topic);
console.log("=========================================");
console.log("");
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
mqttClient.subscribe(topic); // Set Topic Subscribe
console.log("");
console.log("=========================================");
console.log("[Mqtt] : onSubscribe : Success");
console.log("---------------------------------------");
console.log("[topic] : ", topic);
console.log("=========================================");
console.log("");
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onSubscribe] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// [Topic : Publish]
function onPublish(topic, message) {
// --------------------------------------
// Check : Paho Client
// --------------------------------------
if (mqttClient == null){
return;
}
console.log("");
console.log("=========================================");
console.log("[Mqtt] : onPublish : Start");
console.log("---------------------------------------");
console.log("[topic] : ", topic);
console.log("---------------------------------------");
console.log("[message] : ", message);
console.log("=========================================");
console.log("");
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
const pahoMessage = new Paho.Message(message);
pahoMessage.destinationName = topic; // Set Topic Publish
mqttClient.send(pahoMessage);
console.log("");
console.log("=========================================");
console.log("[Mqtt] : onPublish : Success");
console.log("---------------------------------------");
console.log("[topic] : ", topic);
console.log("---------------------------------------");
console.log("[message] : ", message);
console.log("=========================================");
console.log("");
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onPublish] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// [Receive : Message]
function onMessageArrived(message) {
// --------------------------------------
// Check : Paho Client
// --------------------------------------
if (mqttClient == null){
return;
}
console.log("");
console.log("=========================================");
console.log("[Mqtt] : receive : onMessageArrived");
console.log("---------------------------------------");
console.log("[message] : ", JSON.stringify(message));
console.log("---------------------------------------");
console.log("[payloadString] : ", message.payloadString);
console.log("=========================================");
console.log("");
// --------------------------------------
// Logic : Procedure
// --------------------------------------
try {
}
catch (exception) {
console.error("");
console.error("=========================================");
console.error("[onMessageArrived] : [Exception] : 예외 상황 발생");
console.error("-----------------------------------------");
console.error(exception.name);
console.error("-----------------------------------------");
console.error(exception.message);
console.error("=========================================");
console.error("");
}
}
// --------------------------------------------------------------------------------------------------------------
</script>
</head>
<body>
</body>
</html>
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------
[간단 소스] 자바스크립트 paho-mqtt 라이브러리 사용해 MQTT 기본 Connection 연결 수행 실시
https://kkh0977.tistory.com/8414
https://blog.naver.com/kkh0977/224083727154
MQTT (Message Queueing Telemetry Transport) 통신 설명
https://kkh0977.tistory.com/3631
https://blog.naver.com/kkh0977/222971771381?trackingCode=blog_bloghome_searchlist
[라이브러리] [Android] paho.mqtt.android - MqttAndroidClient 안드로이드 MQTT 통신 라이브러리
https://blog.naver.com/kkh0977/223557263865?trackingCode=blog_bloghome_searchlist
[MQTT] mosquitto 사용해 MQTT 통신 테스트 환경 구축
https://blog.naver.com/kkh0977/222971768497?trackingCode=blog_bloghome_searchlist
[mqtt] 온라인 MQTT 테스트 수행 참고 사이트
https://blog.naver.com/kkh0977/223557261164?trackingCode=blog_bloghome_searchlist
-----------------------------------------------------------------------------------------
728x90
반응형
'투케이2K 유틸파일' 카테고리의 다른 글
Comments
