mqtt ssl 上传数据

需求:有多个系统需要将时序数据上传到他们系统中,其中一个是ssl通信方式。

设计:  使用springboot  创建多个mqtt客户端的bean。

代码:

  pom中增加:

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

<dependency>
   <groupId>org.bouncycastle</groupId>
   <artifactId>bcprov-jdk15on</artifactId>
   <version>${bcprov-jdk15on.version}</version>
</dependency>

mqtt  bean:

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLSocketFactory;


public class MqttClientBean {

    private static Logger logger = LoggerFactory.getLogger(MqttClientBean.class);

    public MqttClient mqttClient;
    private MemoryPersistence memoryPersistence;
    private MqttConnectOptions mqttConnectOptions;
    private SSLSocketFactory sslSocketFactory;

    private  String clientId;
    private  String mqUrl;
    private  String userName;
    private  String password;
    private  String keepAlive;

    public MqttClientBean(String clientId,String mqUrl,String userName,String password,String keepAlive,SSLSocketFactory sslSocketFactory){
        this.clientId=clientId;
        this.mqUrl=mqUrl;
        this.userName=userName;
        this.password=password;
        this.keepAlive=keepAlive;
        this.sslSocketFactory=sslSocketFactory;
    }

    public  void start(){
        //初始化连接设置对象
        mqttConnectOptions = new MqttConnectOptions();
        //初始化MqttClient
        if(null != mqttConnectOptions) {
            //true可以安全地使用内存持久性作为客户端断开连接时清除的所有状态
            mqttConnectOptions.setCleanSession(true);
            //设置连接超时
            mqttConnectOptions.setConnectionTimeout(90);
            //设置会话心跳时间
            mqttConnectOptions.setKeepAliveInterval(Integer.valueOf(keepAlive)*1000);
            mqttConnectOptions.setUserName(userName);
            mqttConnectOptions.setPassword(password.toCharArray());
            mqttConnectOptions.setAutomaticReconnect(true);
            try {
                if(sslSocketFactory!=null){
                    mqttConnectOptions.setSocketFactory(sslSocketFactory);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //设置持久化方式
            memoryPersistence = new MemoryPersistence();
            if(null != memoryPersistence && null != clientId) {
                try {
                    mqttClient = new MqttClient(mqUrl, clientId,memoryPersistence);
                    new MqttClient(mqUrl,clientId,memoryPersistence);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }else {

            }
        }else {
            logger.error("mqttConnectOptions对象为空");
        }

        logger.info(String.valueOf(mqttClient.isConnected()));
        //设置连接和回调
        if(null != mqttClient) {
            if(!mqttClient.isConnected()) {

                //创建回调函数对象
                MqttClientRecieveCallback mqttReceriveCallback = new MqttClientRecieveCallback();
                //客户端添加回调函数
                mqttClient.setCallback(mqttReceriveCallback);
                //创建连接
                try {
                    logger.info("创建连接");
                    mqttClient.connect(mqttConnectOptions);
                    logger.info("mqtt连接成功");
                } catch (MqttException e) {
                    e.printStackTrace();
                }

            }
        }else {
            logger.warn("mqttClient为空");
        }
        logger.info(String.valueOf(mqttClient.isConnected()));
    }

    // 关闭连接
    public void closeConnect() {
        //关闭存储方式
        if(null != memoryPersistence) {
            try {
                memoryPersistence.close();
            } catch (MqttPersistenceException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else {
            logger.warn("memoryPersistence is null");
        }

        //关闭连接
        if(null != mqttClient) {
            if(mqttClient.isConnected()) {
                try {
                    mqttClient.disconnect();
                    mqttClient.close();
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }else {
                logger.error("mqttClient is not connect");
            }
        }else {
            logger.error("mqttClient is null");
        }
    }

    // 发布消息
    public void publishMessage(String pubTopic,String message,int qos) {
        if(null != mqttClient&& mqttClient.isConnected()) {
            logger.info("发布消息   "+mqttClient.isConnected());
            logger.info("id:"+mqttClient.getClientId());
            MqttMessage mqttMessage = new MqttMessage();
            mqttMessage.setQos(qos);
            mqttMessage.setPayload(message.getBytes());

            MqttTopic topic = mqttClient.getTopic(pubTopic);

            if(null != topic) {
                try {
                    MqttDeliveryToken publish = topic.publish(mqttMessage);
                    if(!publish.isComplete()) {
                        logger.info("消息发布成功");
                    }
                } catch (MqttException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }else {
            reConnect();
        }
    }

    // 重新连接
    public void reConnect() {
        if(null != mqttClient) {
            if(!mqttClient.isConnected()) {
                if(null != mqttConnectOptions) {
                    try {
                        mqttClient.connect(mqttConnectOptions);
                        logger.info("mqtt连接成功");
                    } catch (MqttException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }else {
                    logger.error("mqttConnectOptions is null");
                }
            }else {
                logger.error("mqttClient is null or connect");
            }
        }else {
            start();
        }
    }

    // 订阅主题
    public void subTopic(String topic) {
        if(null != mqttClient&& mqttClient.isConnected()) {
            try {
                mqttClient.subscribe(topic, 1);
            } catch (MqttException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else {
            logger.error("mqttClient is error");
        }
    }

    // 清空主题
    public void cleanTopic(String topic) {
        if(null != mqttClient&& !mqttClient.isConnected()) {
            try {
                mqttClient.unsubscribe(topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }else {
            logger.error("mqttClient is error");
        }
    }
}

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

public class MqttClientRecieveCallback implements MqttCallback{

    @Override
    public void connectionLost(Throwable cause) {

    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        System.out.println("Client 接收消息主题 : " + topic);
        System.out.println("Client 接收消息Qos : " + message.getQos());
        System.out.println("Client 接收消息内容 : " + new String(message.getPayload()));


    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {

    }

}

使用Configuration创建2个bean:


import com.crc.project.pi.domain.HsePointBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ResourceUtils;

import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.util.HashMap;

@Configuration
public class MqttConfiguration {

    @Value("${mqtt.crsems.clientId}")
    private  String crsems_clientId;
    @Value("${mqtt.crsems.mqUrl}")
    private  String crsems_mqUrl;
    @Value("${mqtt.crsems.userName}")
    private  String crsems_userName;
    @Value("${mqtt.crsems.password}")
    private  String crsems_password;
    @Value("${mqtt.crsems.keepAlive}")
    private  String crsems_keepAlive;

    @Value("${mqtt.dianli.clientId}")
    private  String dianli_clientId;
    @Value("${mqtt.dianli.mqUrl}")
    private  String dianli_mqUrl;
    @Value("${mqtt.dianli.userName}")
    private  String dianli_userName;
    @Value("${mqtt.dianli.password}")
    private  String dianli_password;
    @Value("${mqtt.dianli.keepAlive}")
    private  String dianli_keepAlive;

    @Autowired
    @Qualifier("crsemsSSLSocketFactory")
    private SSLSocketFactory sslSocketFactory;


    @Bean(name="crsemsMqttClient",initMethod="start",destroyMethod="closeConnect")
    public MqttClientBean createCrsemsMqttClient(){
        return new MqttClientBean(crsems_clientId,crsems_mqUrl,crsems_userName,crsems_password,crsems_keepAlive,sslSocketFactory);
    }

    @Bean(name="dianliEnergyMqttClient",initMethod="start",destroyMethod="closeConnect")
    public MqttClientBean createDianliMqttClient(){
        return new MqttClientBean(dianli_clientId,dianli_mqUrl,dianli_userName,dianli_password,dianli_keepAlive,null);
    }



}

创建SSLSocketFactoryBean:

package com.crc.project.pi.bean;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;


@Configuration
public class ConfigCrsemsSSLSocketFactoryBean{

    private static final Logger logger = LoggerFactory.getLogger(ConfigCrsemsSSLSocketFactoryBean.class);
    private static SSLSocketFactory selfSignKeystoreSocketFactory = null;

    @Value("${mqtt.crsems.ssl-client-keystore-file}")
    private  String clientCertPath;
    @Value("${mqtt.crsems.ssl-client-keystore-pwd}")
    private  String clientCertPassword;
    @Value("${mqtt.crsems.ssl-client-key-pair-alias}")
    private  String clientPairAlias;
    @Value("${mqtt.crsems.ssl-client-key-pair-pwd}")
    private  String clientPairPwd;

    @Value("${mqtt.crsems.ssl-trusted-keystore-file}")
    private  String caPath;
    @Value("${mqtt.crsems.ssl-trusted-keystore-alias}")
    private  String caAlias;
    @Value("${mqtt.crsems.ssl-trusted-keystore-pwd}")
    private  String caPassword;

    @Autowired
    ResourceLoader resourceLoader;


    @Bean(name="crsemsSSLSocketFactory")
    public  SSLSocketFactory getSelfSignKeystoreSocketFactory()
    {
        if (selfSignKeystoreSocketFactory == null)
        {
            Security.addProvider(new BouncyCastleProvider());
            String trustedKeyStoreFile = caPath;
            String trustedKeyStoreAlias = caAlias;
            String trustedKeyStorePwd = caPassword;
            logger.info(trustedKeyStoreFile);
            if (StringUtils.isEmpty(trustedKeyStoreFile))
            {
                logger.error("=== Trusted keystore file is empty!");
                return null;
            }
            if (StringUtils.isEmpty(trustedKeyStorePwd))
            {
                logger.error("=== Trusted keystore password is empty!");
                return null;
            }


            TrustManagerFactory tmf = null;
            try
            {
                KeyStore tks = KeyStore.getInstance("JKS");
                Resource keyStoreFileResource = resourceLoader.getResource("classpath:"+trustedKeyStoreFile);
                InputStream tKeyStoreFile = keyStoreFileResource.getInputStream();
                tks.load(tKeyStoreFile, trustedKeyStorePwd.toCharArray());
                tmf = TrustManagerFactory.getInstance("X509");
                tmf.init(tks);
            }
            catch (KeyStoreException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (IOException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (CertificateException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }


            String clientKeyStoreFile = clientCertPath;
            String clientKeyStorePwd = clientCertPassword;
            String clientKeyPairAlias = clientPairAlias;
            String clientKeyPairPwd = clientPairPwd;
            if (StringUtils.isEmpty(clientKeyStoreFile))
            {
                logger.error("=== Client keystore file is empty!");
                return null;
            }
            if (StringUtils.isEmpty(trustedKeyStorePwd))
            {
                logger.error("=== Client keystore password is empty!");
                return null;
            }
            if (StringUtils.isEmpty(clientKeyPairPwd))
            {
                logger.error("=== Client keypair password is empty!");
                return null;
            }

            KeyManagerFactory kmf = null;
            try
            {
                KeyStore cks = KeyStore.getInstance(KeyStore.getDefaultType());
                Resource trustKeyFileResource = resourceLoader.getResource("classpath:"+clientCertPath);
                InputStream cKeyStoreFile = trustKeyFileResource.getInputStream();
                cks.load(cKeyStoreFile, clientKeyStorePwd.toCharArray());

                kmf = KeyManagerFactory.getInstance(
                        KeyManagerFactory.getDefaultAlgorithm());
                kmf.init(cks, clientKeyPairPwd.toCharArray());
            }
            catch (KeyStoreException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (IOException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (CertificateException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }
            catch (UnrecoverableKeyException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
            }


            try
            {
                SSLContext context = SSLContext.getInstance("TLSv1.2");
                context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
                selfSignKeystoreSocketFactory = context.getSocketFactory();
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
                return null;
            }
            catch (KeyManagementException e)
            {
                e.printStackTrace();
                logger.error(e.getMessage());
                return null;
            }
            return selfSignKeystoreSocketFactory;
        }
        return selfSignKeystoreSocketFactory;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值