문제 해결
실패한 단계부터 확인하고, 앞 단계가 정상일 때 다음 단계로 넘어가세요.
| 지금 보이는 증상 | 시작할 진단 |
|---|---|
| 설치 실패, npm 오류, 웹 화면이 안 열림 | 설치·실행 |
| 화면은 열리지만 ready가 안 됨 | 서버 연결 |
| ready인데 메시지가 안 보임 | 메시지 전달 |
| 장치가 검색되지 않거나 LED가 안 바뀜 | 장치 검색·출력 |
| 재접속·화면 전환 후 같은 메시지가 여러 번 표시됨 | 중복 수신 |
| 같은 인증 정보로 다른 곳에서 접속한 뒤 기존 연결이 끊기고 다시 접속하지 않음 | 중복 로그인 |
1. 설치·실행에서 막힐 때
iosignal-examples 저장소의 웹 채팅 예제를 기준으로 합니다.
| 순서 | 확인 방법·정상 결과 | 다르면 할 일 |
|---|---|---|
| 1 | node --version, npm --version이 버전을 출력 | 명령을 찾지 못하면 Node.js·npm을 설치하고 터미널을 다시 엽니다. 예제 package.json의 engines 조건을 확인합니다. |
| 2 | 현재 폴더에 package.json, package-lock.json이 있음 | 저장소 루트가 아니라 iosignal_vanilla-chat 등 예제 폴더로 이동합니다. |
| 3 | npm ci가 오류 없이 끝남 | 네트워크·프록시 오류와 잠금 파일 불일치를 구분합니다. 수정하지 않은 예제에서도 불일치하면 받은 버전과 오류를 기록합니다. 잠금 파일 삭제를 첫 해결책으로 사용하지 마세요. |
| 4 | npm run dev가 웹 주소와 IOSignal 포트를 출력 | EADDRINUSE 또는 포트 사용 중 오류라면 같은 예제를 이미 실행한 터미널을 찾아 종료합니다. 포트를 바꿀 때는 서버와 클라이언트 설정을 함께 맞춥니다. |
| 5 | Vanilla 웹 주소 http://localhost:5175에서 화면이 열림 | WebSocket 주소를 브라우저 주소창에 넣지 않았는지 확인합니다. 다른 예제라면 해당 웹 포트를 사용하세요. |
화면이 열리면 서버 연결로 진행합니다. 브라우저 번들링 중 Node 모듈 오류가 나면 클라이언트 import가 브라우저 진입점 iosignal/io인지 확인하세요.
2. ready가 표시되지 않을 때
| 순서 | 확인 방법·정상 결과 | 다르면 할 일 |
|---|---|---|
| 1 | 서버 터미널이 실행 중이고 ready 또는 listening 로그가 있음 | 빠른 시작은 서버를 먼저 실행합니다. 채팅 예제의 npm run dev는 서버를 함께 시작합니다. preview만 실행했다면 별도 npm run server가 필요합니다. |
| 2 | 클라이언트 URL이 실행한 서버와 일치 | 빠른 시작 WS는 7777, Vanilla 채팅 WS는 7779입니다. 웹 화면 포트 5175와 구분하세요. |
| 3 | 서버와 클라이언트가 같은 기기이면 localhost로 연결 | 다른 기기의 서버에는 그 서버의 LAN 주소나 도메인을 사용합니다. 방화벽과 서버 수신 주소도 확인하세요. |
| 4 | 페이지·연결 방식이 환경에 맞음 | HTTPS 웹앱에서 WS가 차단되면 신뢰할 수 있는 인증서가 설정된 WSS를 사용합니다. 주소 문자열만 wss로 바꾸면 서버에 TLS가 생기지 않습니다. |
| 5 | 브라우저 개발자 도구의 Console·Network에서 연결 오류가 없고 화면이 ready | 인증서·인증·접속 거부·로컬 네트워크 권한 등 실제 오류를 확인합니다. 인증 정보는 서버 등록값과 대조하되 로그에 비밀 키를 남기지 않습니다. |
ready이면 메시지 전달로 진행합니다. URL·포트 선택은 연결 환경과 서버 주소, 인증 실패는 서버 인증 설정을 참고하세요.
3. ready인데 메시지가 안 보일 때
| 순서 | 확인 방법·정상 결과 | 다르면 할 일 |
|---|---|---|
| 1 | 송신자·수신자 모두 같은 IOSignal 서버에 연결 | React·Svelte·Vanilla 예제는 기본 서버 포트가 서로 다릅니다. 같은 예제의 웹 주소를 두 탭에서 엽니다. |
| 2 | 구독 태그와 송신 태그가 정확히 일치 | 채팅은 openchat, 빠른 시작은 hello#message입니다. 대소문자와 #, @, $ 위치까지 대조하세요. |
| 3 | 일반 채널은 구독 요청을 먼저 보내고 송신 | listen() 자동 구독은 ready 핸들러 뒤에 전송됩니다. ready 안에서 구독 직후 송신해야 하면 subscribe() 다음 signal() 순서를 사용하세요. |
| 4 | 직접 명령은 대상 CID로 보내고 직접 수신 핸들러로 처리 | 장치CID@는 장치에서 @로 수신합니다. 직접 수신을 message에서 기다리거나 subscribe('@topic')하지 마세요. |
| 5 | 실제 수신 태그·데이터가 예상대로 도착 | 데이터는 오는데 UI가 안 바뀌면 핸들러의 형식 검사와 화면 상태 갱신을 확인합니다. 송신 로그만으로 상대 수신을 판단하지 마세요. |
구독 순서, 태그와 전달 방식, 데이터 형식을 참고하세요. 기본·그룹 태그가 홈채널을 사용한다면 양쪽 홈채널 조건도 같아야 합니다.
4. 장치가 검색되지 않거나 출력이 안 바뀔 때
| 순서 | 확인 방법·정상 결과 | 다르면 할 일 |
|---|---|---|
| 1 | ESP32 실습의 시리얼 모니터에 READY CID: 표시 | Wi-Fi(SSID·비밀번호, 2.4GHz 네트워크, 전원)부터 확인합니다. 호스트에는 ws:// 같은 접두어를 넣지 않고 TCP 포트(보통 55488)와 방화벽을 확인합니다. |
| 2 | 웹과 장치가 같은 서버에 연결 | 보드의 서버와 앱이 연결한 서버를 대조합니다. WebSocket·TCP 포트는 서로 다를 수 있습니다. |
| 3 | Remocon에 장치 카드가 표시됨. CLI로는 #notify를 구독하고 #search를 보내 CID나 그룹 채널이 오는지 확인 | 같은 홈채널인지, 스케치가 #search에 응답하는지 확인합니다. 시리얼의 CID를 알면 장치CID@$info를 바로 구독해 검색 문제와 정보 문제를 분리할 수 있습니다. |
| 4 | 카드의 버튼을 누르면 상태가 바뀜 | 스케치가 명령을 받은 뒤 @$state를 보내는지 확인합니다. 명령은 장치 CID로 보내야 하며, 익명 장치가 재접속했다면 CID가 달라집니다. |
| 5 | LED와 장치의 상태 보고가 일치 | 상태는 오지만 LED가 다르면 GPIO 번호·저항·LED 극성·보드 종류를 확인합니다. 상태 보고는 빛을 측정한 값이 아닙니다. |
그룹에서 같은 LED만 움직이면 각 보드의 OUTPUT_INDEX를, RGB가 반응하지 않으면 S3 보드·WS2812 핀과 BINARY 4바이트 payload를, 초기 상태가 없으면 리테인 정책과 장치 연결 상태를 확인하세요.
5. 메시지나 UI가 중복 반응할 때
- 화면을 한 번 열었을 때와 화면 전환·재접속 뒤를 비교합니다. 반복할수록 수신 횟수가 늘면 핸들러나 인스턴스 중복 등록을 확인합니다.
ready마다 핸들러를 다시 등록하지 말고, 한 번 등록한 핸들러와 재접속 시 구독을 분리합니다.- 해당 화면만 소유한 IO는 종료 시
destroy()를 호출합니다. 공유 IO라면 화면의unlinkAll(component)또는 등록한 핸들러만 해제합니다. - 직접 토픽은 공통
@와 정확한@topic이벤트가 모두 발생합니다. 양쪽에 같은 처리 코드를 등록했거나 수동emit(tag, ...)전달이 남았는지 확인합니다. - 같은 동작을 다시 실행해 메시지 하나당 의도한 UI 변경이 한 번만 발생하는지 확인합니다.
자세한 소유권 규칙은 컴포넌트 수명주기, 이전 버전과 차이는 버전과 호환성을 참고하세요.
6. 같은 인증 정보로 두 곳에서 접속할 때
- 서버의
duplicateLogin설정을 확인합니다. 기본값keepNew(8.0.0부터)에서는 나중 연결이 이기고, 기존 JS 클라이언트는auth_clear후 멈추며 Arduino는IO_STOP이 됩니다.keepOld에서는 나중 연결이auth_fail을 받습니다. - 장치·앱마다 별도 인증 정보를 발급합니다. 같은 키를 여러 장치가 공유하면 서로를 끊습니다.
- 장치가 재부팅 후 다시 접속하지 못하면
keepOld서버에서 이전 연결이 아직 남아 있는지 확인합니다. heartbeat가 정리한 뒤 다시 접속됩니다.
자세한 정책은 중복 로그인을 참고하세요.
해결되지 않을 때 남길 정보
비밀번호·Device Key·토큰은 제외하고 기록합니다.
사용한 문서 / 예제 폴더:
실패한 진단 단계:
운영체제 / 브라우저 / Node.js 또는 보드 종류:
IOSignal 및 관련 라이브러리 버전:
예제 Git 커밋 또는 다운로드 날짜:
실행 명령 / 서버 주소·포트(비밀 정보 제외):
기대 결과 / 실제 결과:
change·error 출력 / 재현 순서:
실물 확인 순서
- 설치한 Arduino 라이브러리·보드 코어 버전, 보드 종류와 핀 배선이 예제와 일치하는가?
- 컴파일·업로드 후 Wi-Fi에 연결되어 시리얼에
READY CID:가 나타나는가? - 웹과 보드가 같은 서버를 사용하며 웹도
ready인가? - 기본·검색·그룹 태그를 사용할 때 같은 홈채널 환경인가?
- RX의 태그·타입·값이 문서와 같은가?
- 명령을 보낸 뒤 LED 등 물리 출력과 실제 상태 발행이 일치하는가?
- 보드·웹 재접속 후 다시 구독하거나 새 CID를 선택했는가?
- 재접속·전원 재시작 후 리테인 적용과 초기 출력이 맞는가?
컴파일 성공은 실물 통신 검증이 아닙니다. 연결 환경은 서버 주소와 HTTP/HTTPS, 검증 범위는 검증 범위를 확인하세요.