diff --git a/admin-client-temperature.iml b/admin-client-temperature.iml index c93e2f9..4239187 100644 --- a/admin-client-temperature.iml +++ b/admin-client-temperature.iml @@ -1,5 +1,5 @@ - + @@ -10,10 +10,7 @@ - - - - + @@ -21,4 +18,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java b/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java index b95910e..d6e73aa 100644 --- a/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java +++ b/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java @@ -66,14 +66,24 @@ public class AdminClientTemperatureApplication implements CommandLineRunner, App // }else { // log.info("temperatureService is empty"); // } - if (temperatureEspService != null) { + + if (temperatureService != null) { log.info("------------------------"); - log.info("temperatureEspService is not empty"); - MqttDianDengTechClient client = new MqttDianDengTechClient(); - client.start(temperatureEspService); + log.info("TemperatureController is not empty"); + MqttHuaWeiYunClient client = new MqttHuaWeiYunClient(); + client.start(temperatureService); }else { - log.info("temperatureEspService is empty"); + log.info("temperatureService is empty"); } + +// if (temperatureEspService != null) { +// log.info("------------------------"); +// log.info("temperatureEspService is not empty"); +// MqttDianDengTechClient client = new MqttDianDengTechClient(); +// client.start(temperatureEspService); +// }else { +// log.info("temperatureEspService is empty"); +// } } catch (Exception ex) { ex.printStackTrace(); } diff --git a/src/main/java/com/rehome/mqttclienttemperature/MqttDianDengTechClient.java b/src/main/java/com/rehome/mqttclienttemperature/MqttDianDengTechClient.java index 1513634..653003f 100644 --- a/src/main/java/com/rehome/mqttclienttemperature/MqttDianDengTechClient.java +++ b/src/main/java/com/rehome/mqttclienttemperature/MqttDianDengTechClient.java @@ -112,7 +112,7 @@ public class MqttDianDengTechClient { log.info("message RSA:"+strData); if(strData!=null&&strData.length()>=11){ String[] strDataTemperature = strData.split(" "); - temperatureEspService.saveTemperature(strDataTemperature[0],strDataTemperature[1],s); + //temperatureEspService.saveTemperature(strDataTemperature[0],strDataTemperature[1],s); } } diff --git a/src/main/java/com/rehome/mqttclienttemperature/MqttHuaWeiYunClient.java b/src/main/java/com/rehome/mqttclienttemperature/MqttHuaWeiYunClient.java new file mode 100644 index 0000000..3caf020 --- /dev/null +++ b/src/main/java/com/rehome/mqttclienttemperature/MqttHuaWeiYunClient.java @@ -0,0 +1,148 @@ +package com.rehome.mqttclienttemperature; + + + +import com.rehome.mqttclienttemperature.service.TemperatureService; +import com.rehome.mqttclienttemperature.utils.MqttSSLSocketFactory; +import com.rehome.mqttclienttemperature.utils.UUIDUtil; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.*; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import javax.net.ssl.SSLSocketFactory; +import java.io.InputStream; +import java.util.Timer; +import java.util.TimerTask; + + +@Slf4j +public class MqttHuaWeiYunClient { + /** + * 代理服务器ip地址 + */ + public static final String MQTT_BROKER_HOST = "ssl://mqtt.fileview123.com:8883"; + + /** + * 客户端唯一标识 + */ + public static String MQTT_CLIENT_ID = "AppServer_temperature_APP_server_02"; + + /** + *帐号 + */ + public static String USERNAME = "admin"; + /** + * 密码 + */ + public static String PASSWORD = "publish452131wW452131wW$"; + /** + * 订阅标识 + */ + public static String TOPIC_FILTER = "/device/esp8266/+"; + + private volatile static MqttClient mqttClient; + private static MqttConnectOptions options; + private static int qos = 2; + + //定时器 + private Timer timer; + + public MqttHuaWeiYunClient(){ + try { + MQTT_CLIENT_ID = UUIDUtil.getUUID(); + // host为主机名,clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示, + // MemoryPersistence设置clientid的保存形式,默认为以内存保存 + mqttClient = new MqttClient(MQTT_BROKER_HOST, MQTT_CLIENT_ID, new MemoryPersistence()); + // 配置参数信息 + options = new MqttConnectOptions(); + // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录, + // 这里设置为true表示每次连接到服务器都以新的身份连接 + options.setCleanSession(false); + // 设置用户名 + options.setUserName(USERNAME); + // 设置密码 + options.setPassword(PASSWORD.toCharArray()); + // 设置超时时间 单位为秒 + options.setConnectionTimeout(10); + // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制 + options.setKeepAliveInterval(20); + //断线重连 + options.setAutomaticReconnect(true); + //mqtt服务器端单双向加密 + InputStream certInput = this.getClass().getResourceAsStream("/ssn/rootCA.crt"); + InputStream clientCertInput = this.getClass().getResourceAsStream("/ssn/client.p12"); + String password = "12345678"; + SSLSocketFactory socketFactory = MqttSSLSocketFactory.getThreeSocketFactory(certInput,clientCertInput,password); + options.setSocketFactory(socketFactory); + } catch (Exception e) { + e.printStackTrace(); + } + } + public void start(TemperatureService temperatureService) { + try { + // 连接 + mqttClient.connect(options); + // 订阅 + mqttClient.subscribe(TOPIC_FILTER,qos); + // 设置回调 + mqttClient.setCallback(new MqttCallbackExtended(){ + + @Override + public void connectionLost(Throwable throwable) { + log.info("connectionLost"); + try { + mqttClient.reconnect(); + } catch (MqttException e) { + e.printStackTrace(); + } + } + + @Override + public void messageArrived(String s, MqttMessage mqttMessage) { + String strData = new String(mqttMessage.getPayload()); + log.info("topic:"+s); + log.info("Qos:"+mqttMessage.getQos()); + log.info("message RSA:"+strData); + //temperatureService.saveTemperature(strData,s); + } + + @Override + public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { + log.info("deliveryComplete---------"+ iMqttDeliveryToken.isComplete()); + } + + @Override + public void connectComplete(boolean b, String s) { + //连接成功后调用 + try { + mqttClient.subscribe(TOPIC_FILTER,qos);//具体订阅代码 + } catch (MqttException e) { + e.printStackTrace(); + } + } + }); + timer = new Timer(); + timer.schedule(new TimerTask() { + public void run() { + log.info("-------设定要指定任务--------"); + try { + //判断拦截状态,这里注意一下,如果没有这个判断,是非常坑的 + if (!mqttClient.isConnected()) { + log.info("***** 没有连接到服务器 *****"); + log.info("***** client to connect *****"); + // 重新连接 + mqttClient.connect(options); + } + if (mqttClient.isConnected()) {//连接成功,跳出连接 + log.info("***** connect success *****"); + } + } catch (MqttException e1) { + e1.printStackTrace(); + } + } + }, 10000,10000); + // 设定指定的时间time,此处为10000毫秒 + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/rehome/mqttclienttemperature/utils/MqttSSLSocketFactory.java b/src/main/java/com/rehome/mqttclienttemperature/utils/MqttSSLSocketFactory.java index 8809702..855ccc5 100644 --- a/src/main/java/com/rehome/mqttclienttemperature/utils/MqttSSLSocketFactory.java +++ b/src/main/java/com/rehome/mqttclienttemperature/utils/MqttSSLSocketFactory.java @@ -10,13 +10,16 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import java.io.BufferedInputStream; +import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.security.KeyPair; import java.security.KeyStore; import java.security.Security; +import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.util.Collection; public class MqttSSLSocketFactory { public static SSLSocketFactory getSingleSocketFactory(InputStream caCrtFileInputStream) throws Exception { @@ -133,4 +136,35 @@ public class MqttSSLSocketFactory { return sslContext.getSocketFactory(); } + public static SSLSocketFactory getThreeSocketFactory(InputStream certInput, InputStream clientCertInput,String password) throws Exception { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Collection certs = cf.generateCertificates(certInput); + + // 将服务器端 CA 证书存入 KeyStore + KeyStore tmKs = KeyStore.getInstance(KeyStore.getDefaultType()); + tmKs.load(null, null); + int index = 0; + for (Certificate cert : certs) { + tmKs.setCertificateEntry("server_ca_" + index++, cert); + } + + // 创建 TrustManager + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(tmKs); + + // 将客户端证书存入 KeyStore + //String password = "mypassword"; //与导出密码一致 + KeyStore kmKs = KeyStore.getInstance("PKCS12"); + kmKs.load(clientCertInput, password.toCharArray()); + + // 创建 KeyManager + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(kmKs, password.toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + // SSLContext 中设置好 KeyManager 和 TrustManager + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + //SSLSocketFactory socketFactory = sslContext.getSocketFactory(); + return sslContext.getSocketFactory(); + } } diff --git a/src/main/resources/ssn/client.p12 b/src/main/resources/ssn/client.p12 new file mode 100644 index 0000000..cec7418 Binary files /dev/null and b/src/main/resources/ssn/client.p12 differ diff --git a/src/main/resources/ssn/rootCA.crt b/src/main/resources/ssn/rootCA.crt new file mode 100644 index 0000000..cff1ca9 --- /dev/null +++ b/src/main/resources/ssn/rootCA.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5TCCAs2gAwIBAgIUI/GSmRnvgR3EeADRel5pdCosFykwDQYJKoZIhvcNAQEL +BQAwgYAxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAlndWFuZ2RvbmcxDzANBgNVBAcM +BnpodWhhaTEPMA0GA1UECgwGcmVob21lMQ8wDQYDVQQLDAZyZWhvbWUxCzAJBgNV +BAMMAkNBMR0wGwYJKoZIhvcNAQkBFg5od2Y0NTJAMTYzLmNvbTAgFw0yNTExMTIw +ODM3NTVaGA8yMTI1MTAxOTA4Mzc1NVowgYAxCzAJBgNVBAYTAkNOMRIwEAYDVQQI +DAlndWFuZ2RvbmcxDzANBgNVBAcMBnpodWhhaTEPMA0GA1UECgwGcmVob21lMQ8w +DQYDVQQLDAZyZWhvbWUxCzAJBgNVBAMMAkNBMR0wGwYJKoZIhvcNAQkBFg5od2Y0 +NTJAMTYzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOkSAxyB +b8kjM5+pzc4kjuWvgXR6w9UJgCl+uLFhqMTcco7VOK7mBfuykK980ICm7W+i+pi0 +jpg8LCIkZv6G7oB8CAmrqNF4D4H8v0Z0eeFZtNC20eFn3mCwpetOyH6nT8ivsKJf +ap8sXKTVzqvIn1OCFiAbVqOLH+Aq3Ixd8s24+G5NcOWNSnMarZH074UCWKPLU3sq +NDYBnmR29+0LyWouA/XIloUpEgYZqujS3FmxQEt0TDbrrJRZyCFwV5E+nWVom5j0 +HGLSUUocqvdT9EuRsyOT7BgbHlMjMf0Q24Za5b+j0zAE5UePlJAVyPSpOtFgbqDE +7u8fV0AuHrB17LkCAwEAAaNTMFEwHQYDVR0OBBYEFEvK+GTdVABY+1Afs5X3SF1l +Wm3wMB8GA1UdIwQYMBaAFEvK+GTdVABY+1Afs5X3SF1lWm3wMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFW4O0CHWhvJc7i8FaT2y30DPKvAqRqM +fIyANbrQEsf+R8GcvUz/jJmD1VHBksb75fH+Zy5vBMnohP/iHFNNUmYVp3wrFfrk +SvHsB6Vtk8WYKNtklnEqiucLMwvcuMw2MOIoUVCZh4Gl37qOQqBu2rYslZicgyft +RbW5d8Y0zspl8wJSTbVS5Lf6rm8ze3EXja1/HVMek+aG7gAS39Dq9op0llw0ldhZ +jLFI1/xJJBxJvN4KQFLrX7V9hjfvM6BsWXcf9GEPHmy0kfgRBUCA+EpVa4BaQY6p +ebLMi0rRbpFDnc2CIPdf2JOhGOmcrFymIFc/MzYpfP7uUAJiXBb2KIM= +-----END CERTIFICATE-----