Unread messages (small red dots), the front-end and RabbitMQ real-time message push practice, thief is simple~

fc4aede907f7f5b83c703746eb7a5f9a.jpegA few days ago, a small partner in the fan group asked: web How to implement the unread messages (small red dots) on the page is relatively simple. Just this week, there is a similar development task on hand, so I simply sorted it out for my friends’ reference. Days can be used.

Previously, in  "springboot + rabbitmq for smart home"  , it was mentioned that rabbitmq the MQTT protocol can be used  to  push the instructions of the smart home. It also mentioned that  the message push can be  MQTT done webwith the protocol  , and the unread message ( 小红点) function is just applied to the real-time message push Up.

MQTT I won’t go into details about the agreement anymore. If you haven’t touched it before, let’s review the previous article. Today, it’s still practice-oriented!

6855f72665957565c53a1d1d7fe5ac72.png

web There are many ways to implement real-time message push on the end, but it is always the same. The bottom layer basically depends on it websocket, and the MQTT protocol is no exception.

RabbitMQ build

RabbitMQI won’t go into details about the basic construction of Baidu. It’s not a big problem to do it step by step with Baidu. Here are two more important configurations.

1. Open the mqtt protocol

By default, RabbitMQit is not open MQTT protocol, so we need to manually open the associated plug-ins, and RabbitMQthe MQTT agreement is divided into two.

The first one  rabbitmq_mqtt provides interactive use with back-end services and corresponds to the port 1883.

rabbitmq-plugins enable rabbitmq_mqtt

The second type  rabbitmq_web_mqtt provides interactive use with the front end and corresponds to the port 15675.

rabbitmq-plugins enable rabbitmq_web_mqtt 

If RabbitMQ you see the following display in the  management background, it means that the MQTT protocol has been opened successfully, and the middleware environment has been set up.

e159d8125e01bba89db99cec41435891.pngProtocol corresponding port number

The MQTT default exchange Exchange of the protocol  is used  amp.topic, and the topic we subscribe to will  Queues register a client queue, and the route  Routing key is the topic we set.

1e65ae8703fe572a995cccccc1ba1ee5.pngSwitch information

Server message sending

web Terminal real-time message push is generally a one-way push, and the front-end receives the message pushed by the server to display, so only message sending is required.

1. Mqtt client dependency package

Introduction  spring-integration-mqtt, org.eclipse.paho.client.mqttv3 implementation of two toolkits

<!--mqtt依赖包-->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mqtt</artifactId>
</dependency>

<dependency>
    <groupId>org.eclipse.paho</groupId>
       <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
    <version>1.2.0</version>
</dependency>

2. Message sender

Message sending is relatively simple, mainly applied to  @ServiceActivator annotations, you need to pay attention to the messageHandler.setAsyncattributes, if set to  false, it may block when the asynchronous mode is turned off to send messages.

@Configuration
public class IotMqttProducerConfig {

    @Autowired
    private MqttConfig mqttConfig;

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setServerURIs(mqttConfig.getServers());
        return factory;
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    @Bean
    @ServiceActivator(inputChannel = "iotMqttInputChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttConfig.getServerClientId(), mqttClientFactory());
        messageHandler.setAsync(false);
        messageHandler.setDefaultTopic(mqttConfig.getDefaultTopic());
        return messageHandler;
    }
}

MQTT When sending messages to the outside world  API , you need to use  @MessagingGateway annotations to provide a message gateway proxy, and the parameters  defaultRequestChannel specify the binding of sending messages channel.

Three types of APIinterfaces can be implemented , payload including the message topic sent, the subject of the qos message sent, and the message quality.

@MessagingGateway(defaultRequestChannel = "iotMqttInputChannel")
public interface IotMqttGateway {

    // 向默认的 topic 发送消息
    void sendMessage2Mqtt(String payload);
    // 向指定的 topic 发送消息
    void sendMessage2Mqtt(String payload,@Header(MqttHeaders.TOPIC) String topic);
    // 向指定的 topic 发送消息,并指定服务质量参数
    void sendMessage2Mqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}

Front-end news subscription

The front-end is implemented using tools corresponding to the server  paho-mqtt mqttws31.js. The implementation is similar to the traditional  websocket way. The core methods  client = new Paho.MQTT.Client and various monitoring events are relatively simple in code.

Note : To ensure clientIdthe global uniqueness of the front and back ends  , I simply use random numbers here to solve

<script type="text/javascript">
        // mqtt协议rabbitmq服务
        var brokerIp = location.hostname;
        // mqtt协议端口号
        var port = 15675;
        // 接受推送消息的主题
        var topic = "push_message_topic";

        // mqtt连接
        client = new Paho.MQTT.Client(brokerIp, port, "/ws""clientId_" + parseInt(Math.random() * 10010));

        var options = {
            timeout3//超时时间
            keepAliveInterval: 30,//心跳时间
            onSuccess: function () {
                console.log(("连接成功~"));
                client.subscribe(topic, {qos1});
            },
            onFailurefunction (message{
                console.log(("连接失败~" + message.errorMessage));
            }
        };
        // 考虑到https的情况
        if (location.protocol == "https:") {
            options.useSSL = true;
        }
        client.connect(options);
        console.log(("已经连接到" + brokerIp + ":" + port));

        // 连接断开事件
        client.onConnectionLost = function (responseObject{
            console.log("失去连接 - " + responseObject.errorMessage);
        };

        // 接收消息事件
        client.onMessageArrived = function (message{
            console.log("接受主题: " + message.destinationName + "的消息: " + message.payloadString);
            $("#arrivedDiv").append("<br/>"+message.payloadString);
            var count = $("#count").text();
            count = Number(count) + 1;
            $("#count").text(count);
        };

        // 推送给指定主题
        function sendMessage() {
            var a = $("#message").val();
            if (client.isConnected()) {
                var message = new Paho.MQTT.Message(a);
                message.destinationName = topic;
                client.send(message);
            }
        }
    </script>

test

There are not many front-end and back-end codes. Let's test it and make a page to see the effect.

First postman send the message with the  simulated backend

http://127.0.0.1:8080/fun/sendMessage?message=我是程序员内点事&topic=push_message_topic

7fe3ae9efe41d100e6a737ad3be8d972.pngSimulate sending messages

Look at the effect of the front-end subscribing to messages again, and see that the messages are pushed to the front-end in real time. Here, only the number of unread messages is counted, and generally a list of unread messages is also made.

2d0f53ed419fe5ba5439f5fd8910b2b4.gifReal-time message push animation

to sum up

Unread messages is a very common function, no matter whether it is a  webterminal or a mobile terminal system, it is a necessary module. The MQTTprotocol is only one of the implementation methods, or it is necessary to master a method. The specific tools used to implement it still depend on the specific business scenarios and learning costs. For example, I RabbitMQ also consider some operation and maintenance costs in it.


The complete code address of this article :https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-mqtt-messagepush


Guess you like

Origin blog.51cto.com/14989525/2547187