일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Replication
- setInterval 외부 정지
- map이 undefined가 뜰 때
- pm2 시작
- pm2
- mosquitto
- 맥 어드레스
- AntDesign
- mosquitto.conf
- DatePicker
- pm2 확인
- invalid data
- setInterval clear
- c# datagridview 데이터 넣기
- 서버동기화
- setInterval 중지
- 데이터테이블 데이터 넣기
- datagridview 직접입력
- allow_anonymouse
- listener 1883
- 1883
- 공인IP
- timepicker
- setInterval 정지
- pm2 설치
- mySQL_Replication
- transfer
- DataGridView 직접 입력
- pm2 상태 확인
- html #select #option #multiple
- Today
- Total
개발 노트
[Next.js] web worker을 이용한 mqtt와 웹소켓 적용하기 본문
mqtt
MQTT - The Standard for IoT Messaging
Why MQTT? Lightweight and Efficient MQTT clients are very small, require minimal resources so can be used on small microcontrollers. MQTT message headers are small to optimize network bandwidth. Bi-directional Communications MQTT allows for messaging betwe
mqtt.org
web socket
참고: https://ko.wikipedia.org/wiki/%EC%9B%B9%EC%86%8C%EC%BC%93
웹소켓 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 웹소켓(WebSocket)은 하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜이다. 웹소켓 프로토콜은 2011년 IETF에 의해 RFC 6455로 표준화되었으며 웹
ko.wikipedia.org
web worker
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
Web Workers API - Web APIs | MDN
Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usuall
developer.mozilla.org
web worker 적용하기
1. 기존에 Mqtt와 웹소켓을 적용한 코드
'use client';
import mqtt, { MqttClient } from 'mqtt';
import React, { useEffect, useState } from 'react';
const mqttUri = 'ws://127.0.0.1:9001';
const options: mqtt.IClientOptions = {
clientId: 'nextjs',
reconnectPeriod: 2000,
};
const Mqtt: React.FC = () => {
const [messages, setMessages] = useState<string[]>(['init']);
const addMessage = () => {
const newMessages = [...messages, Math.random().toString()];
setMessages(newMessages);
};
useEffect(() => {
const client: MqttClient | undefined = mqtt.connect(mqttUri, options);
console.dir(client);
client.subscribe('#');
client.on('message', (topic, message) => {
setMessages((prevMessages) => [...prevMessages,topic+ ' : ' +message.toString()]);
});
return () => {
if (client) {
client.unsubscribe('#');
client.end();
}
};
}, []);
return (
<div>
<button
className='border'
onClick={addMessage}>addMessage</button>
<h2>Received Messages: </h2>
<ul>
{messages.map((message, index) => (
<li key={index}>{message}</li>
))}
</ul>
</div>
);
};
export default Mqtt;
2. public에 mqttWorker.ts만들기
// mqttWorker.ts
import mqtt, { MqttClient } from 'mqtt';
const mqttUri = 'ws://127.0.0.1:9001';
const options: mqtt.IClientOptions = {
clientId: 'nextjs',
reconnectPeriod: 2000,
};
self.addEventListener('message', (e) => {
const client: MqttClient | undefined = mqtt.connect(mqttUri, options);
client.subscribe('#');
client.on('connect',()=>{
console.log('connected');
})
client.on('error', (error) => {
postMessage('Error: ' + error.message);
});
client.on('message', (topic, message) => {
postMessage(topic + ' : ' + message.toString());
});
});
3. mqttWorker를 빌드하기 위해 webpack.worker.config.js만들기
const WorkerPlugin = require('worker-plugin');
const path = require('path');
module.exports = {
mode: 'production',
target: 'webworker',
entry: './public/mqttWorker.ts',
output: {
filename: 'mqttWorker.built.js',
path: path.resolve(__dirname, 'public'),
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [
{ test: /\.tsx?$/, loader: 'ts-loader' },
],
},
plugins: [
new WorkerPlugin()
]
};
4. build용 package설치하기
pnpm add webpack webpack-cli worker-plugin ts-loader
//package.json
{
"name": "controlweb",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"build:worker": "webpack --config webpack.worker.config.js"
},
"dependencies": {
"mqtt": "^5.3.5",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18",
"worker-plugin": "^5.0.1",
"zustand": "^4.5.0"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.1.0",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"ts-loader": "^9.5.1",
"typescript": "^5",
"webpack": "^5.90.1",
"webpack-cli": "^5.1.4"
}
}
5. src\component\MqttWorker.tsx만들기
'use client';
import React, { useEffect, useRef } from 'react';
import { useMqttStore } from '@/store/useMqttStore';
const MqttWorker: React.FC = () => {
const { messages, addMessage } = useMqttStore();
const workerRef = useRef<Worker | null>(null); // 웹 워커 참조를 저장하는 ref
useEffect(() => {
const URL = '/mqttWorker.built.js';
const worker = new Worker(URL);
workerRef.current = worker; // 웹 워커 객체를 ref에 저장
worker.onmessage = function (event) {
addMessage(event.data); // Zustand 스토어의 addMessage 액션 사용
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const startMqtt = () => {
if (workerRef.current) {
workerRef.current.postMessage({ CMD: 'MQTT_START' }); // 웹 워커에 메시지 보내기
}
};
const stopMqtt = () => {
if (workerRef.current) {
workerRef.current.postMessage({ CMD: 'MQTT_STOP' }); // 웹 워커에 메시지 보내기
}
};
const subscribeMqtt = () => {
if (workerRef.current) {
workerRef.current.postMessage({
CMD: 'MQTT_SUBSCIBE',
DATA: ['dawoon/ALIVE/#', 'dawoon/Robot/#', '/dawoon/RMAN/#', 'dawoon/Feeder/#'],
}); // 웹 워커에 메시지 보내기
}
};
return (
<div className='relative flex flex-col w-full'>
<ul className='fixed flex gap-2 justify-center w-full bg-[#d6dbdc] p-2 shadow-lg'>
<li >
<button
className='border bg-white px-2.5 py-1.5 rounded-3xl shadow-xl border-gray-400 hover:bg-gray-600 hover:text-white active:bg-[#121212] active:text-white'
onClick={startMqtt}>
startMqtt
</button>
</li>
<li>
<button
className='border bg-white px-2.5 py-1.5 rounded-3xl shadow-xl border-gray-400 hover:bg-gray-600 hover:text-white active:bg-[#121212] active:text-white'
onClick={stopMqtt}>
stopMqtt
</button>
</li>
<li>
<button
className='border bg-white px-2.5 py-1.5 rounded-3xl shadow-xl border-gray-400 hover:bg-gray-600 hover:text-white active:bg-[#121212] active:text-white'
onClick={subscribeMqtt}>
subscribeMqtt
</button>
</li>
</ul>
<h2 className='ml-2 text-lg font-semibold mt-16'>Received Messages: </h2>
<ul className='flex flex-col gap-y-2 px-2'>
{messages.map((message: string, index: number) => (
<li
className='bg-white border px-2.5 py-1.5 rounded-xl'
key={index}>
{message}
</li>
))}
</ul>
</div>
);
};
export default MqttWorker;
6. Mqtt에서 받아온 값을 전역으로 관리하기 위해 useMqttStore.tsx만들기
// useMqttStore.ts
import { create } from 'zustand';
type Store = {
messages: string[];
addMessage: (message: string) => void;
};
export const useMqttStore = create<Store>((set) => ({
messages: [],
addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })),
}));
'React' 카테고리의 다른 글
[실패]mqtt로 받은 메세지 컴포넌트 내부에 전달 (0) | 2024.02.23 |
---|---|
MQTT/web-worker 다중 컴포넌트 연동 (0) | 2024.02.22 |
webWorker관련 참고자료 (0) | 2024.02.05 |
Next.js 13 이상 localization 적용하기 (0) | 2024.01.22 |
Next.js 13 이상 국제화(i18n) 적용 (0) | 2024.01.19 |