나는 qos에 대해 약간 혼란 스럽습니다. qos에 대해 읽었습니다. qos가 2로 설정된 경우 브로커 / 클라이언트가 4 단계 핸드 셰이크를 사용하여 정확히 한 번 메시지를 전달합니다.
따라서 qos 2는 메시지가 가입자 (클라이언트)가 수신하지 않고 브로커에 게시되었음을 확인합니다. 또는 구독자가 메시지를 받거나
승인을 위해 우리는 게시자가 "DATA"와 같은 주제로 메시지를 게시하고 "ACK"와 같은 주제를 구독하고 구독자는 주제에 대해 메시지가 수신되었다는 주제 "ACK"에 대한 승인을 게시해야하는 것과 같은 응용 프로그램을 설정해야합니다. "데이터"
데이터 게시를위한 Java 클래스와 게시자를 구독하기위한 다른 클래스를 만들었습니다.
다음 코드에서 qos 2에서 게시하려고 시도했으며 deliveryComplete 함수에서 qos 0으로 시도했을 때 getMessage ()를 시도 할 때 예외가 발생했습니다. getMessage ()가 예외를주지 않았습니다.
public class PublishMe implements MqttCallback{
MqttClient myClient;
MqttClient myClientPublish;
MqttConnectOptions connOpt;
MqttConnectOptions connOptPublish;
static final String BROKER_URL = "tcp://Ehydromet-PC:1883";
static Boolean msgACK=false;
public static void main(String[] args) {
PublishMe smc = new PublishMe();
smc.runClient();
}
@Override
public void connectionLost(Throwable t) {
System.out.println("Connection lost!");
}
@Override
public void messageArrived(String string, MqttMessage message) throws Exception {
System.out.println("-------------------------------------------------");
System.out.println("| Topic:" + string);
System.out.println("| Message: " + new String(message.getPayload()));
System.out.println("-------------------------------------------------");
}
/**
*
* deliveryComplete
* This callback is invoked when a message published by this client
* is successfully received by the broker.
*
* @param token
*/
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
try{
System.out.println("Message delivered successfully to topic : \"" + token.getMessage().toString() + "\".");
}catch(Exception ex){
System.out.println(ex.getCause()+" -- "+ex.getLocalizedMessage()+" -- "+ex.getMessage()+" -- " );
}
}
public void runClient() {
connOpt = new MqttConnectOptions();
connOpt.setCleanSession(false);
connOpt.setKeepAliveInterval(0);
connOptPublish= new MqttConnectOptions();
connOptPublish.setCleanSession(false);
connOptPublish.setKeepAliveInterval(0);
// Connect to Broker
try {
myClient = new MqttClient(BROKER_URL, "pahomqttpublish11");
myClient.setCallback(this);
myClient.connect(connOpt);
myClientPublish= new MqttClient(BROKER_URL, "pahomqttpublish42");
myClientPublish.setCallback(this);
myClientPublish.connect(connOptPublish);
} catch (MqttException e) {
e.printStackTrace();
System.exit(-1);
}
System.out.println("Connected to " + BROKER_URL);
String myTopic = "sample";
// String myTopic = "receiveDATA2";
MqttTopic topic = myClientPublish.getTopic(myTopic);
// publish messages if publisher
if (publisher) {
int i=1;
while(true){
String pubMsg = "sample msg "+i;
MqttMessage message = new MqttMessage(pubMsg.getBytes());
System.out.println(message);
message.setQos(2);
message.setRetained(false);
// Publish the message
MqttDeliveryToken token = null;
try {
// publish message to broker
token = topic.publish(message);
// Wait until the message has been delivered to the broker
token.waitForCompletion();
msgACK=false;
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
이하는 구독자입니다
public class Mqttsample implements MqttCallback{
MqttClient myClient;
MqttClient myClientPublish;
MqttConnectOptions connOpt;
MqttConnectOptions connOptPublish;
static final String BROKER_URL = "tcp://Ehydromet-PC:1883";
// the following two flags control whether this example is a publisher, a subscriber or both
static final Boolean subscriber = true;
static final Boolean publisher = true;
public static void main(String[] args) {
Mqttsample smc = new Mqttsample();
smc.runClient();
}
@Override
public void connectionLost(Throwable t) {
System.out.println("Connection lost!");
// code to reconnect to the broker would go here if desired
}
@Override
public void messageArrived(String string, MqttMessage message) throws Exception {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
System.out.println("| Topic:" + string+"| Message: " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
try{
System.out.println("Pub complete" + new String(token.getMessage().getPayload()));
}
catch(Exception ex ){
System.out.println("delivery Error "+ex.getMessage());
}
}
public void runClient() {
connOpt = new MqttConnectOptions();
connOpt.setCleanSession(false);
connOpt.setKeepAliveInterval(0);
connOptPublish= new MqttConnectOptions();
connOptPublish.setCleanSession(false);
connOptPublish.setKeepAliveInterval(0);
// Connect to Broker
try {
myClient = new MqttClient(BROKER_URL, "pahomqttpublish");
myClient.setCallback(this);
myClient.connect(connOpt);
myClientPublish= new MqttClient(BROKER_URL, "pahomqttsubscribe");
myClientPublish.setCallback(this);
myClientPublish.connect(connOptPublish);
} catch (MqttException e) {
e.printStackTrace();
System.exit(-1);
}
System.out.println("Connected to " + BROKER_URL);
// subscribe to topic if subscriber
if (subscriber) {
try {
//String myTopicACK = M2MIO_DOMAIN + "/" + "ACK" + "/" + M2MIO_THING;
String myTopicACK = "sample";
// MqttTopic topicACK = myClient.getTopic(myTopicACK);
int subQoS = 2;
myClient.subscribe(myTopicACK, subQoS);
} catch (Exception e) {
e.printStackTrace();
}
}
//
}
}
구독자가 메시지를 받았는지 확인하려면 어떻게해야합니까? 게시자 코드에서 구현해야하는 것은 무엇입니까?
위 링크에서 http://www.eclipse.org/paho/files/mqttdoc/Cclient/qos.html
QoS2, 정확히 한 번 : 메시지가 항상 정확히 한 번 전달됩니다. 메시지는 보낸 사람이받는 사람이 메시지를 게시했다는 확인을받을 때까지 보낸 사람에게 로컬로 저장되어야합니다. 메시지를 다시 보내야하는 경우를 대비하여 메시지가 저장됩니다. QoS2는 가장 안전하지만 가장 느린 전송 모드입니다.
확인했듯이 더 높은 QOS 수준은 클라이언트 (게시자 또는 구독자)와 브로커 간의 메시지 전달만을 설명하며 종단 간 게시자 간 메시지 전달을 설명하지 않습니다.
발행 / 구독 프로토콜로서 토픽에 얼마나 많은 구독자가있을 수 있는지 알 수있는 방법이 없기 때문에 이것은 매우 신중합니다. 0과 n 사이의 숫자가있을 수 있습니다. 또한 게시자와 구독자는 서로 다른 QOS 수준에서 주제와 상호 작용할 수 있습니다 (게시자는 QOS 2에서 게시 할 수 있고 구독자는 QOS 0에서 구독 할 수 있음). 메시지는 보관 된 메시지로 게시 될 수도 있으므로 마지막으로 보관 된 메시지가 항상 새로 구독하는 클라이언트로 전달됩니다.
QOS 계약을 충족하기 위해 클라이언트의 모든 스토리지는 사용중인 MQTT 라이브러리 (이 경우 Paho)에서 처리해야합니다.
deliveryComplete
콜백 게시자가 브로커에게 메시지를 송신 완료 만 표시된다. 또한 문서 는 token.getMessage()
메시지가 전달되면 null을 반환하여 언급 한 예외를 설명 한다고 말합니다 (예외를 포함하지 않았으므로 여기에서 추측해야 함).
응용 프로그램 아키텍처에서 메시지에 대한 종단 간 승인이 실제로 필요한 경우 설명했던 것과 유사한 것을 구현해야합니다. 그러나 제대로 작동하는지 확인하려면 메시지의 페이로드에 메시지 ID를 포함해야하며 확인 메시지에는이를 포함해야하며 메시지를받은 사람을 알 수 있도록 응답하는 구독자를 식별하는 방법이 있어야합니다. 내가 이와 같은 것을 사용하는 유일한 이유는 메시지를 확인하는 데 시간이 필요한 경우입니다. 시간이 관련 요소가 아닌 경우 영구 세션 을 사용하여 메시지가 게시시 연결이 끊어진 경우 다시 연결할 때 구독 클라이언트에 전달되는지 확인합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다