2012-06-20 3 views
9

나는 MQTT를 평가하여 대규모 시스템을위한 핵심 메시징 플랫폼으로 사용하기로 결정했다. 가장 큰 이유는 프로토콜이 얼마나 컴팩트한지와 실제로 구현할 수있는 방법이 쉽기 때문입니다. MQTT에 관한 한 가지 문제가 있는데 다음 질문에 대한 대답을 찾고 있습니다.MQTT messageId 실용적인 구현

QoS1 및 QoS2 메시지는 클라이언트로부터 확인을 요구합니다. PUBACK, PUBREC, PUBREL 및 PUBCOMP를 수신 할 때 메시지를 식별하는 유일한 방법은 messageId와 clientId입니다. 메시지 아이디는 부호없는 int16이므로 최대 값은 65535입니다. 1 년에 15 개의 QoS2 메시지를 보내고 장시간 실행하는 클라이언트에게는 충분하지 않은 것으로 보입니다.

메시지를 식별하는 다른 방법이 있는지 잘 모르겠습니다. 가능한 한 표준을 준수하고 싶습니다.

답변

19

아마 첫 번째 요점은 메시지 ID가 클라이언트 및 방향별로 처리된다는 것입니다. 즉 브로커는 연결되어있는 각 클라이언트에 대해 QoS> 0 인 각 보내는 메시지에 대한 메시지 ID를 만들고 이러한 메시지 ID는 다른 클라이언트에 게시 된 동일한 메시지에 사용 된 다른 메시지 ID와 완전히 독립적 일 것입니다. 마찬가지로 각 클라이언트는 보내는 메시지에 대해 자체 메시지 ID를 생성합니다.

메시지 ID가 고유 할 필요는 없으므로 QoS 레벨 2로 시간당 15 개의 메시지를 보내는 클라이언트는 어떤 시점에서 단순히 오버플로됩니다. 실제 제한은 한 번에 방향 (즉, 메시지 핸드 셰이크의 일부분)에서 최대 65535 개의 메시지 만있을 수 있다는 것입니다. 주어진 ID를 가진 메시지가 완전히 처리되면 해당 메시지 ID를 다시 사용할 수 있습니다.

또 다른 방법은 메시지가 전송되는 속도 또는 메시지 처리 방식에 따라 클라이언트가 한 번에 한 메시지 만 보낸 경우 어떻게 작동하는지 고려하는 것입니다 . 이 경우 메시지가 중복 될 확률이 없으므로 모든 메시지에 대해 메시지 ID를 1로 설정할 수 있습니다.

비행 중에 여러 개의 메시지가있는 것을 지원하려면 새 메시지를 할당하기 전에 메시지 ID 중복이 없는지 확인하는 것이 상대적으로 간단합니다.

클라이언트마다 메시지 ID가 있으므로> 65535 개의 클라이언트에 단일 메시지를 보내면 메시지 ID 충돌이 발생할 수 없습니다. 한 번에> 65535 개의 메시지를 각 클라이언트에 보내면 메시지 흐름이 완료되지 않으면 문제가 발생합니다. 주석 응답

"나는 모든 MQTT 브로커가 마지막 QoS1/2 메시지를 전달하는 경향이 나타났습니다"

브로커 만이 알고 클라이언트에 메시지를 보내드립니다. 처음으로 연결하는 경우 하나의 예외 (보관 된 메시지 제외)를 통해 과거의 메시지를 가져올 방법이 없습니다. 메시지가 보관되도록 설정된 경우 "마지막으로 성공한"값입니다. 새로운 클라이언트가 구독하면 보존 된 메시지가 즉시 전송되어 드물게 업데이트되는 것들에 유용합니다. 나는 이것이 당신이 말하는 것을 의심합니다. 클라이언트가 연결되지 않은 상태에서 대기중인 메시지를 갖도록하려면 클라이언트를 영구적으로 유지하려면 "클린 세션"옵션을 사용하지 않도록 설정해야합니다. 또한 QoS> 0 구독 및 QoS> 0 게시를 사용해야합니다. 클라이언트가 다시 연결되면 (클린 세션이 계속 비활성화 됨으로 설정 됨) 대기중인 메시지가 배달됩니다. 일반적으로 브로커에서 이러한 방식으로 대기열에 추가 할 메시지 수를 구성 할 수 있습니다.이 경우 추가 메시지가 삭제됩니다. 중요한 점은 이전에 연결하지 않은 클라이언트의 큐 메시지가 의도적으로 지원되지 않는다는 것입니다.

+0

나는이 점을 이해하며, 답장을 보내 주셔서 감사드립니다. 모든 MQTT 브로커는 마지막 QoS1/2 메시지 만 전달하는 경향이 있다는 것을 알고 있습니다. 더 많은 것을 제공하고 싶다면 어떻게해야합니까? 65535 이상은 무엇입니까? 나는 이것이 가능하지 않을 수도 있음을 이해하지만 그것은 가능하다. 제안하는 솔루션은 알려진 수의 수신자에게 유용합니다. 제가 처리하고있는 상황은 얼마나 많은 수령자가 있을지 모르고 아직도 공장에 있는지 모릅니다. 기본적으로 그들은 거기에있을 수 있지만 결코 들어올 수 없습니다. 그리고 수천 명의 사람들이있을 수 있습니다. – radekg

+0

내가 분명히 말하지 않은 한 가지 점은 메시지 ID가 클라이언트와 방향별로 있다는 것입니다. 나는 그것을 포함하도록 답을 업데이트했다. – ralight

+0

다른 답변을했습니다. 그래도 문제가 해결되지 않으면 다른 의견을 남겨주세요. – ralight

0

QOS1 또는 QOS2에서 더 많은 메시지를 전달하려면 지속적 메모리 개념을 사용해야합니다. 이 때 가입자가 사용 가능하지 않을 때 메시지는 지속적 메모리에 저장되어 가입자가 연결되면 전달됩니다. mosquitto.conf 파일을 구성한 후에도 QOS0에서이 작업을 수행 할 수 있습니다.