Show my code!
MqttObject.class
package com.zsmart.zcm.nms.mqtt;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
@Slf4j
public class MqttObject {
MqttClient mqttClient = null;
//让构造函数为 private
private MqttObject(){}
//创建 SingleObject 的一个对象
private static MqttObject instance = new MqttObject();
//获取唯一可用的对象
public static MqttObject getInstance(){
return instance;
}
// 开启客户端
public MqttClient startClient() {
try {
mqttClient = new MqttClient("ssl://192.168.111.199:31884", "data-compensate");
// MQTT 连接选项
MqttConnectOptions connOpts = new MqttConnectOptions();
// 保留会话
connOpts.setCleanSession(true);
// 设置超时时间
connOpts.setConnectionTimeout(30);
// 设置会话心跳时间
connOpts.setKeepAliveInterval(60);
// 设置自动重连
connOpts.setAutomaticReconnect(true);
//忽略证书验证--单向认证不需要的
connOpts.setHttpsHostnameVerificationEnabled(false);
connOpts.setSocketFactory(SslUtil.getSocketFactory("C:\\influxdbx3\\src\\main\\resources\\cacert.pem", "C:\\influxdbx3\\src\\main\\resources\\cert.pem", "C:\\influxdbx3\\src\\main\\resources\\key.pem", ""));
// 建立连接
mqttClient.connect(connOpts);
System.out.println("Mqtt Connecting to broker success!");
} catch (MqttException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return mqttClient;
}
// 关闭客户端
public void closeClient() {
try {
mqttClient.disconnect();
mqttClient.close();
System.out.println("Mqtt Disconnect to broker !");
} catch (MqttException e) {
e.printStackTrace();
}
}
// 发送消息
public void sendToMqtt(String data, String topic) {
MqttMessage message = new MqttMessage();
if (data != null) {
message.setQos(1);
message.setRetained(true);
try {
message.setPayload(data.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
try {
mqttClient.publish(topic, message);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
SslUtil.class
package com.zsmart.zcm.nms.mqtt;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.X509Certificate;
public class SslUtil {
public static SSLSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile,
final String password) throws Exception {
Security.addProvider(new BouncyCastleProvider());
// load CA certificate
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate)reader.readObject();
reader.close();
// load client certificate
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate)reader.readObject();
reader.close();
// load client private key
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
@Override
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair)reader.readObject();
reader.close();
// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(caKs);
// client key and certificates are sent to server so it can authenticate us
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
}
主要jar包的pom.xml引入
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
证书的下载:
直接进入EMQ容器,把证书下载下来,然后加载到代码里!
有问题欢迎留言讨论,不定时回复!
支持开源,拥抱开源,为开发者赋能!