[Finishing] MQTT simple operation using the learning

A brief

MQTT (Message Queuing Telemetry Transport, Message Queuing Telemetry Transport Protocol), is based publish / subscribe "lightweight" communication protocol (publish / subscribe) mode, the agreement built on TCP / IP protocol, by IBM in 1999 on release. MQTT biggest advantage is that the code may be minimal and limited bandwidth for real-time remote devices to provide reliable messaging service. As a low-cost, low bandwidth usage of instant messaging protocol, so there is more widely used in things, small equipment, mobile applications.

MQTT agreement method:

MQTT protocol defines methods (also referred to action), is determined by representation of resources in the operation. This resource data can represent pre-existing or dynamically generated data, depending on the implementation of the server. Generally speaking, it refers to resource files or output on the server. The main methods are:

  • (1) Connect. Waiting to establish a connection to the server.
  • (2) Disconnect. MQTT wait for the client to complete the work, and disconnected from the server TCP / IP session.
  • (3) Subscribe. Waiting to complete the subscription.
  • (4) UnSubscribe. Waiting for the server to cancel one or more clients subscribe to topics.
  • (5) Publish. MQTT client sends a request message, the thread returns to the application program completion of the transmission.

Second, Illustrated

MQTT protocol architecture, with an illustration. For example there is a temperature sensor (1 Machine), 2 small display screen (2 Machine), a display screen to display the temperature value of the temperature sensor.

Need to monitor the agreement by MQTT subscribe (subscription) such as a temperature called the topic (theme):

                                     

When the temperature sensor publish (release) temperature data, the display can receive:

                                 

Note: The above two pictures, taken from MQTT and CoAP, IoT Protocols

  Middleman (Broker)

  Another part MQTT and client collaboration is MQTT broker, which is known as publish / subscribe protocol part of the heart, depending on the specific implementation, a broker can support thousands of concurrent client connections. The main responsibilities of the broker is to accept all messages, after filtration and distribute different messages subscribers.

Third, server

Support MQTT protocol messaging middleware products: There are a lot of MQTT messaging middleware server, the following are the server-side of MQTT agreement.

mosquitto

Eclipse Paho

MQ Telemetry

Apache ActiveMQ

Apache Apollo

……

Installation under Linux environment Mosquitto

Many tutorials, recording error during installation:

  Invalid user 'mosquitto'

 Note: the above two methods to use one on it, that was mind-drawing two before they can be successful. → _ →

After successful installation, you can subscribe to publish communications;

subscription

mosquitto_sub -t my_topic

release

mosquitto_pub -t my_topic -m my_message
 Note: [- h] MQTT server you want to connect the 
   [-T] subscribe to a topic, here mqtt 
  [-V] prints more debugging information
  [-M] specifies the message content

Four, MQTT instance (Java language)

 1.Maven dependence

<!-- MQTT -->
    <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.1.1</version>
    </dependency>

2.ServerMQTT.java

package ServerMQTT;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import Back.PushCallback;

/**
 * 
 * Title:Server Description: 服务器向多个客户端推送主题,即不同客户端可向服务器订阅相同主题
 * 
 */
public class ServerMQTT {

    // tcp://MQTT安装的服务器地址:MQTT定义的端口号
    public static final String HOST = "tcp://192.168.8.101:1884";
    // 定义一个主题
    public static final String TOPIC = "root/topic/testDx";
    // 定义MQTT的ID,可以在MQTT服务配置中指定
    private static final String clientid =     "server11";

    private MqttClient client;
    private MqttTopic topic11;
//    private String userName = "root";
//    private String passWord = "1234qwer";

    private MqttMessage message;

    /**
     * 构造函数
     * 
     * @throws MqttException
     */
    public ServerMQTT() throws MqttException {
        // MemoryPersistence设置clientid的保存形式,默认为以内存保存
        client = new MqttClient(HOST, clientid, new MemoryPersistence());
        connect();
    }

    /**
     * 用来连接服务器
     */
    private void connect() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        // 设置超时时间
        options.setConnectionTimeout(10);
        // 设置会话心跳时间
        options.setKeepAliveInterval(20);
        try {
            client.setCallback(new PushCallback());
            client.connect(options);

            topic11 = client.getTopic(TOPIC);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param topic
     * @param message
     * @throws MqttPersistenceException
     * @throws MqttException
     */
    public void publish(MqttTopic topic, MqttMessage message) throws MqttPersistenceException, MqttException {
        MqttDeliveryToken token = topic.publish(message);
        token.waitForCompletion();
        System.out.println("message is published completely! " + token.isComplete());
    }

    /**
     * 启动入口
     * 
     * @param args
     * @throws MqttException
     */
    public static void main(String[] args) throws MqttException {
        ServerMQTT server = new ServerMQTT();

        server.message = new MqttMessage();
        server.message.setQos(1);
        server.message.setRetained(true);
        server.message.setPayload("hello,topic1日4".getBytes());
        server.publish(server.topic11, server.message);
        System.out.println(server.message.isRetained() + "------ratained状态");
    }
}

3.ClientMQTT.java

package ClientMQTT;
import java.util.concurrent.ScheduledExecutorService;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import Back.PushCallback;

public class ClientMQTT {

    public static final String HOST = "tcp://192.168.8.101:1884";
    public static final String TOPIC = "root/topic/testDx";
    private static final String clientid = "client11";
    private MqttClient client;
    private MqttConnectOptions options;
//    private String userName = "admin";
//    private String passWord = "admin";

    private ScheduledExecutorService scheduler;

    private void start() {
        try {
            // host为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
            client = new MqttClient(HOST, clientid, new MemoryPersistence());
            // MQTT的连接设置
            options = new MqttConnectOptions();
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            // 设置连接的用户名
            //options.setUserName(userName);
//            // 设置连接的密码
//            options.setPassword(passWord.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(10);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            // 设置回调
            client.setCallback(new PushCallback());
            MqttTopic topic = client.getTopic(TOPIC);
            // setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
            options.setWill(topic, "close".getBytes(), 2, true);

            client.connect(options);
            // 订阅消息
            int[] Qos = { 1 };
            String[] topic1 = { TOPIC };
            client.subscribe(topic1, Qos);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws MqttException {
        ClientMQTT client = new ClientMQTT();
        client.start();
    }
}

3.回调PushCallback.java

package Back;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;

/**
 * 发布消息的回调类
 * 
 * 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
 * 每个客户机标识都需要一个回调实例。在此示例中,构造函数传递客户机标识以另存为实例数据。 在回调中,将它用来标识已经启动了该回调的哪个实例。
 * 必须在回调类中实现三个方法:
 * 
 * public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
 * 
 * public void connectionLost(Throwable cause)在断开连接时调用。
 * public void deliveryComplete(MqttDeliveryToken token)) 接收到已经发布的 QoS 1 或 QoS 2
 * 消息的传递令牌时调用。 由 MqttClient.connect 激活此回调。
 * 
 */
public class PushCallback implements MqttCallback {

    public void connectionLost(Throwable cause) {
        // 连接丢失后,一般在这里面进行重连   连接丢失后 
        System.out.println("连接断开,可以做重连");
    }

    public void deliveryComplete(IMqttDeliveryToken token) {
        System.out.println("推送合理呀deliveryComplete---------" + token.isComplete());
    }

    public void messageArrived(String topic, MqttMessage message) throws Exception {
        // subscribe后得到的消息会执行到这里面
        System.out.println("接收消息主题 : " + topic);
        System.out.println("接收消息Qos : " + message.getQos());
        System.out.println("接收消息内容 : " + new String(message.getPayload()));
    }
}

 

Guess you like

Origin www.cnblogs.com/dingxiao/p/10938474.html
Recommended