Spring boot整合MQTT做消息队列

  •  

  •   前言

            Apache Apollo是一个代理服务器,其是在ActiveMQ基础上发展而来的,可以支持STOMP, AMQP, MQTT, Openwire, SSL, and WebSockets 等多种协议。有关Apollo的搭建问题,参阅上一篇部落格。

  •     正文

废话不多言,直接撸代码,先去maven的官网引入mqtt的第三方支持包。

       
            org.eclipse.paho
            org.eclipse.paho.client.mqttv3
            1.2.0
        

        
        
            com.alibaba
            fastjson
            1.2.51
        

  Demo结构:

Spring boot整合MQTT做消息队列_第1张图片

服务端的代码:

package com.example.demo.mqtt.server;


import com.example.demo.mqtt.PushCallback;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * Created by pengcheng.du on 2018/10/12.com.example.demo.mqtt.server.Server
 */
/*服务器端向客户端推送不同的主题*/
public class Server {
    public static final String SERVER_URL = "tcp://0.0.0.0:61613";
    public static List TOPICList = new ArrayList<>(Arrays.asList("wether","car","topic"));
    public static String clientid;

    private MqttClient mqttClient;
    public MqttTopic mqttTopic1;
    private MqttTopic getMqttTopic2;
    private String username = "admin";
    private String password = "password";

    private MqttMessage mqttMessage;

    /*//创建新的topic链接的时候使用此构造方法
    public Server() throws Exception{
        mqttClient = new MqttClient(SERVER_URL, clientid, new MemoryPersistence());
        Server server = new Server();
        server.mqttMessage = new MqttMessage();
        server.mqttMessage.setQos(2);
        server.mqttMessage.setRetained(true);
        server.mqttMessage.setPayload("装配成功".getBytes());
        server.publish(server.mqttTopic1,server.mqttMessage);
        System.out.println(server.mqttMessage.isRetained()+":retained状态");
        connect();
    }*/

    public Server() throws Exception{
        clientid = "wether";
        mqttClient = new MqttClient(SERVER_URL, clientid, new MemoryPersistence());
        String topic = "wether";
        connect(topic);
    }
    public Server(String topic,String clientid) throws Exception{
        TOPICList.add(topic);
        mqttClient = new MqttClient(SERVER_URL, clientid, new MemoryPersistence());
        this.createCon(topic);
        //connect(topic);

    }

    public void connect(String topic){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(false);
        mqttConnectOptions.setUserName(username);
        mqttConnectOptions.setPassword(password.toCharArray());

        mqttConnectOptions.setConnectionTimeout(20);
        mqttConnectOptions.setKeepAliveInterval(20);

        try {
            mqttClient.setCallback(new PushCallback());
            mqttClient.connect(mqttConnectOptions);
            mqttTopic1 = mqttClient.getTopic(topic);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    public static void publish(MqttTopic topic,MqttMessage message) throws MqttException {
        System.out.println("话题是"+topic.toString()+"要发送的消息是"+message.toString());
        MqttDeliveryToken publish_token = topic.publish(message);
        publish_token.waitForCompletion();
        System.out.print("消息已经推送到客户端了");
    }
    public static void main(String[] args) throws Exception {
        Server server = new Server();
        server.mqttMessage = new MqttMessage();
        server.mqttMessage.setQos(2);
        server.mqttMessage.setRetained(true);
        server.mqttMessage.setPayload("装配成功".getBytes());
        server.publish(server.mqttTopic1,server.mqttMessage);
        System.out.println(server.mqttMessage.isRetained()+":retained状态");
    }
    public String createCon(String topic) throws Exception{
        Server server = new Server();
        server.mqttMessage = new MqttMessage();
        server.mqttMessage.setQos(2);
        server.mqttMessage.setRetained(true);
        server.mqttMessage.setPayload("装配成功".getBytes());
        server.publish(server.getMqttClient().getTopic(topic),server.mqttMessage);
        System.out.println(server.mqttMessage.isRetained()+":retained状态");
        return "build success";
    }

    public static String getServerUrl() {
        return SERVER_URL;
    }

    public List getTOPIC() {
        return TOPICList;
    }

    public static String getClientid() {
        return clientid;
    }

    public MqttClient getMqttClient() {
        return mqttClient;
    }

    public MqttTopic getMqttTopic1() {
        return mqttTopic1;
    }

    public MqttTopic getGetMqttTopic2() {
        return getMqttTopic2;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public MqttMessage getMqttMessage() {
        return mqttMessage;
    }
}

Client端:

package com.example.demo.mqtt.client;

import com.example.demo.mqtt.PushCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by pengcheng.du on 2018/10/12.
 */
public class Client {
    public static final String SERVER_URL = "tcp://0.0.0.0:61613";
    public static final String TOPIC = "wether";
    public static final String clientid  = "client4";

    private MqttClient client;
    private MqttConnectOptions options;
    private String userName = "admin";
    private String passWord = "password";

    private ScheduledExecutorService scheduler;

    private void start() throws Exception{
        client = new MqttClient(SERVER_URL, clientid, new MemoryPersistence());
        options = new MqttConnectOptions();
        options.setCleanSession(true);
        options.setUserName(userName);
        options.setPassword(passWord.toCharArray());
        options.setConnectionTimeout(20);
        options.setKeepAliveInterval(20);
        client.setCallback(new PushCallback());
        MqttTopic topic = client.getTopic(TOPIC);
        client.connect(options);
        int[] Qos = {1};
        String[] topic1 = {TOPIC};
        client.subscribe(topic1,Qos);
    }

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


}

发送断开回调 PushCallback.java

package com.example.demo.mqtt;

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

/**
 * Created by pengcheng.du on 2018/10/12.
 */
public class PushCallback implements MqttCallback {
    @Override
    //处理链接断开
    public void connectionLost(Throwable throwable) {
        // 连接丢失后,一般在这里面进行重连
        System.out.println("连接断开,可以做重连");
    }

    @Override
    //处理消息送达
    public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
        System.out.println("接收消息主题 : " + s);
        System.out.println("接收消息Qos : " + mqttMessage.getQos());
        System.out.println("接收消息内容 : " + new String(mqttMessage.getPayload()));

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
    }
}

开放开放两个接口,作为触发点,亦可以使用其他方式:

package com.example.demo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.mqtt.client.Client;
import com.example.demo.mqtt.server.Server;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by pengcheng.du on 2018/10/12.
 */
@RestController
public class PublishMessage {
    private static String HOST = "tcp://0.0.0.0:61613";
    public static MqttClient client;

    public static final String SERVER_URL = "tcp://0.0.0.0:61613";
    //推送消息
    @RequestMapping(value = "mqtt/publishMessageOnTopic/{topic}",method = RequestMethod.POST)
    public Map publishMessageOnTopic(
            @PathVariable(value = "topic") String topic, @RequestBody String message) throws Exception {
        Map map = new HashMap<>();
        JSONObject jsonObject = (JSONObject) JSONObject.parse(message);
        String mess = (String) jsonObject.get("message");
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(mess.getBytes());
        mqttMessage.setQos(2);
        mqttMessage.setRetained(true);
        if (this.findIndex(topic) == -1) {
            map.put("data","no topic");
            return map;
        }
        int index = this.findIndex(topic);
        Server server = new Server();
        server.connect(topic);
        MqttTopic mqttTopic1 = server.mqttTopic1;
        Server.publish(mqttTopic1,mqttMessage);
        map.put("data","已发送");
        return map;
    }
    public int findIndex(String topic) throws Exception{
        Server server = new Server();
        final List topicList = server.getTOPIC();
        int Idnex = 0;
        for (String topic1: topicList) {
            if (topic.equals(topic1)) {
                break;
            }
            Idnex++;
        }
        if (Idnex==topicList.size()) {
            return -1;
        } else {
            return Idnex;
        }
    }
    private  MqttClient getMqttClient(String clientId) throws MqttException {
        if (client != null && clientId.equals(client.getClientId())) {
            return client;
        }
        return new MqttClient(HOST, clientId);
    }
    //创建主题
    @RequestMapping(value = "mqtt/createNewTopic/{topic}/{clientId}",method = RequestMethod.POST)
    public Map createNewTopic(@PathVariable(value = "topic") String topic ,
                                             @PathVariable(value = "clientId") String clientId){
        System.out.println("topic:"+topic+",clientId"+clientId);
        try{
            Server server = new Server(topic,clientId);
            //server.connect(topic);
            MqttTopic topic1 = server.getMqttClient().getTopic("");
            System.out.println("topic1:"+topic1);
        } catch (Exception e){
            System.out.println(e.toString());
        }

        return null;
    }
}

运行结果:自上而下是请求触发,服务端的控制,两个客户端的控制台,均通过tcp协议获取到了订阅的话题message。

Spring boot整合MQTT做消息队列_第2张图片

Spring boot整合MQTT做消息队列_第3张图片

Spring boot整合MQTT做消息队列_第4张图片

  • 总结:

MQTT只是一种消息推送的协议目前(2016/1/13)为V3.1版本,而Apache Apollo是更具这种协议而开发的一款服务性的服务程序,被用来进行消息推送。Apache Apollo说白了其实很简单,就是在服务器端创建一个唯一订阅号,发送者可以向这个订阅号中发东西,然后接受者(即订阅了这个订阅号的人)都会收到这个订阅号发出来的消息。以此来完成消息的推送。服务器其实是一个消息中转站。

你可能感兴趣的:(java,消息队列)