전달 문제
연결은 되었는데 데이터가 기대대로 오가지 않을 때 이 문서를 봅니다.
먼저 시뮬레이터 상태의 sent, acknowledged, received, rejected, error를 확인합니다.
받은 메시지가 거부될 때
섹션 제목: “받은 메시지가 거부될 때”rejected가 늘고 error가 OPC UA PubSub …이면 메시지는 도착했지만 시뮬레이터 구독자가 받아들이지 않은 것입니다.
error |
원인 | 해결 |
|---|---|---|
OPC UA PubSub Malformed |
MQTT 5.0 메시지에 Content Type이나 User Property UAMessageType이 없거나, 같은 속성이 두 번 있거나, 값 형식이 틀렸습니다. |
발행자가 application/opcua+uadp와 UAMessageType=ua-data를 붙이게 합니다. |
OPC UA PubSub Conflict |
속성 값이 이 구독과 다릅니다. 예: Content Type application/json이나 UAMessageType ua-metadata |
발행자의 인코딩과 메시지 종류를 UADP 데이터로 맞춥니다. |
OPC UA PubSub Unsupported |
페이로드가 서명과 암호화 없는 UADP NetworkMessage가 아닙니다. | 발행자가 보안 없는 UADP를 보내는지 확인합니다. |
OPC UA PubSub Limit |
받은 메시지가 64 KiB를 넘거나 속성이 너무 많습니다. | 메시지를 나눕니다. |
시뮬레이터가 보내는 메시지와 같은 형식이 필요하면 시뮬레이터로 발행·구독에서 실제 바이트를 확인합니다.
시작하자마자 rejected가 1인 경우
섹션 제목: “시작하자마자 rejected가 1인 경우”다른 도구가 시뮬레이터 토픽에 잘못된 보존 메시지를 남겨 두었을 때입니다. 브로커는 구독할 때마다 보존 메시지를 보내므로 PubSub를 시작할 때마다 같은 거부가 반복됩니다. 다음 명령으로 그 토픽의 보존 메시지를 지웁니다.
mosquitto_pub -V 5 -r -n -t opcua/uadp/data/77/demo메시지가 오지 않을 때
섹션 제목: “메시지가 오지 않을 때”| 증상 | 원인 | 해결 |
|---|---|---|
| 구독자를 늦게 시작하면 이전 데이터가 없음 | 시뮬레이터는 보존 메시지를 쓰지 않고 매번 새 세션으로 연결합니다. 구독 전 메시지는 받을 수 없습니다. | 구독자를 먼저 시작합니다. |
관찰자에는 보이는데 received가 그대로 |
토픽이 다릅니다. 대소문자와 끝의 /까지 정확히 같아야 합니다. |
MQTT topic을 발행자와 똑같이 맞춥니다. |
| 시작은 성공했는데 아무것도 오지 않음 | 브로커가 읽기 권한이 없는 메시지를 전달하지 않습니다. Mosquitto는 구독 자체는 성공으로 응답합니다. | ACL에 topic read <토픽>을 추가합니다. |
dropped가 늘어남 |
받은 메시지를 꺼내지 않아 대기열(256개)이 찼습니다. | Show received나 pubsub_received를 더 자주 실행합니다. |
발행이 거부되거나 실패할 때
섹션 제목: “발행이 거부되거나 실패할 때”| 위치와 문장 | 원인 | 해결 |
|---|---|---|
상태 error: MQTT publish refused: 0x87 |
브로커가 PUBACK 0x87(Not authorized)로 거부했습니다. 발행 권한이 없습니다. acknowledged가 늘지 않습니다. |
ACL에 topic write <토픽>을 추가합니다. |
상태 error: MQTT publish refused: 0x.. |
그 밖의 PUBACK 실패 코드입니다. 예: 0x97 Quota exceeded, 0x90 Topic Name invalid | MQTT 5.0 기능의 표에서 찾습니다. |
MQTT publish failed: unsupported MQTT session feature: broker publication capabilities |
브로커의 Maximum QoS가 0입니다(Mosquitto max_qos 0). 시뮬레이터는 QoS 1로만 발행합니다. |
브로커가 QoS 1을 받도록 설정합니다. |
MQTT publish failed: MQTT session resource limit |
메시지가 브로커가 알린 Maximum Packet Size(Mosquitto max_packet_size)를 넘습니다. 시뮬레이터는 보내지 않습니다. |
브로커 한도를 늘리거나 필드를 줄입니다. |
OPC UA PubSub Limit |
인코딩한 UADP 메시지가 64 KiB를 넘습니다. | 필드 수나 문자열 길이를 줄입니다. |
PUBACK의 0x10(No matching subscribers)은 성공 코드이므로 acknowledged에 포함됩니다.
구독자가 없어도 발행은 성공합니다.
QoS와 보존 메시지 때문에 헷갈리는 경우
섹션 제목: “QoS와 보존 메시지 때문에 헷갈리는 경우”| 관찰 | 설명 |
|---|---|
mosquitto_sub 출력이 qos=0 |
관찰자가 QoS 0으로 구독했기 때문입니다. 브로커는 메시지 QoS와 구독 QoS 중 낮은 값으로 보냅니다. -q 1로 구독하면 qos=1이 보입니다. |
| 같은 Sequence가 두 번 보임 | QoS 1은 최소 한 번 전달이므로 다시 보낸 메시지가 올 수 있습니다. 순번으로 중복을 거릅니다. 다른 도구가 같은 바이트를 다시 발행해도 같은 순번이 됩니다. |
| PubSub를 다시 시작할 때마다 같은 메시지가 옴 | 그 토픽에 보존 메시지가 있습니다. 위의 mosquitto_pub -r -n으로 지웁니다. |
| 여러 발행자의 메시지 순서가 섞임 | MQTT는 한 클라이언트가 한 토픽에 보낸 메시지의 순서만 지킵니다. 발행자 사이의 순서는 정해져 있지 않습니다. |