车辆上线动态获取主题,代码对接完成

master
DongZeLiang 2023-11-28 11:06:41 +08:00
parent 8413e2e627
commit 7fd2e3481e
9 changed files with 241 additions and 34 deletions

14
pom.xml
View File

@ -75,6 +75,20 @@
<artifactId>fastjson2</artifactId>
<version>2.0.42</version>
</dependency>
<!-- http调用框架 -->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.33</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
</dependencies>
</project>

View File

@ -23,11 +23,6 @@ public interface VehicleInstanceService {
*/
public void init(Vehicle vehicle);
/**
*
* @param vin VIN
*/
public void initClient(String vin);
/**
*

View File

@ -1,7 +1,6 @@
package com.muyu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.muyu.domain.PositionRouteInfo;
import com.muyu.common.Result;
import com.muyu.domain.Vehicle;
import com.muyu.domain.model.PositionModel;
import com.muyu.domain.req.CheckPositionReq;
@ -11,16 +10,20 @@ import com.muyu.domain.req.VehicleInstanceListReq;
import com.muyu.domain.resp.VehicleInstanceResp;
import com.muyu.service.PositionRouteService;
import com.muyu.service.VehicleInstanceService;
import com.muyu.utils.MD5Util;
import com.muyu.vehicle.VehicleInstance;
import com.muyu.vehicle.api.ClientAdmin;
import com.muyu.vehicle.api.req.VehicleConnectionReq;
import com.muyu.vehicle.core.LocalContainer;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.vehicle.model.properties.MqttProperties;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
/**
* @author DongZeLiang
@ -35,6 +38,12 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
@Autowired
private PositionRouteService positionRouteService;
@Autowired
private ClientAdmin clientAdmin;
@Value("${mqtt.server.host}")
private String broker;
/**
*
*
@ -49,23 +58,6 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
log.info("构建车辆对象: [{}]", vehicle.getVin());
}
/**
*
*
* @param vin VIN
*/
@Override
public void initClient(String vin) {
VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(vin);
MqttProperties mqttProperties = MqttProperties.builder()
.broker("tcp://fluxmq.muyu.icu:1883")
.topic("test")
.clientId(vin)
.build();
vehicleInstance.setMqttProperties(mqttProperties);
vehicleInstance.initClient();
}
/**
*
*
@ -92,13 +84,25 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
if (vehicleInstance == null){
throw new RuntimeException("没有【"+vin+"】车辆");
}
vehicleInstance.setMqttProperties(
MqttProperties.builder()
.broker("tcp://fluxmq.muyu.icu:1883")
.topic("test")
.clientId(vin)
.build()
);
String timestamp = String.valueOf(System.currentTimeMillis());
VehicleConnectionReq connectionReq = VehicleConnectionReq.builder()
.vin(vin)
.timestamp(timestamp)
.userName(MD5Util.encrypted(vin+timestamp))
.nonce(MD5Util.encrypted(UUID.randomUUID().toString().replace("-", "")))
.build();
Result<String> result = clientAdmin.vehicleConnection(connectionReq);
if (result.getCode() != 200){
throw new RuntimeException("车辆:["+vin+"],连接异常:["+result.getMsg()+"]");
}
MqttProperties mqttProperties = MqttProperties.builder()
.broker(broker)
.topic(result.getData())
.clientId(vin)
.username(connectionReq.getUserName())
.password(vin+connectionReq.getTimestamp()+connectionReq.getNonce())
.build();
vehicleInstance.setMqttProperties(mqttProperties);
vehicleInstance.initClient();
}

View File

@ -0,0 +1,71 @@
package com.muyu.utils;
import lombok.extern.log4j.Log4j2;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
@Log4j2
public class MD5Util {
private static final Integer SALT_LENGTH = 12;
/**
* byte16
* @param b
* @return
*/
public static String byteToHexString(byte[] b) {
StringBuilder hexString = new StringBuilder();
for (byte value : b) {
String hex = Integer.toHexString(value & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
hexString.append(hex.toUpperCase());
}
return hexString.toString();
}
/**
*
* @param str
* @return
*/
public static String encrypted (String str) {
try {
// 声明加密后的口令数组变量
byte[] pwd = null;
// 随机数生成器
SecureRandom random = new SecureRandom();
// 声明盐数组变量
byte[] salt = new byte[SALT_LENGTH];
// 将随机数放入盐变量中
random.nextBytes(salt);
// 声明消息摘要对象
MessageDigest md = null;
// 创建消息摘要
md = MessageDigest.getInstance("MD5");
// 将盐数据传入消息摘要对象
md.update(salt);
// 将口令的数据传给消息摘要对象
md.update(str.getBytes(StandardCharsets.UTF_8));
// 获得消息摘要的字节数组
byte[] digest = md.digest();
// 因为要在口令的字节数组中存放盐,所以加上盐的字节长度
pwd = new byte[digest.length + SALT_LENGTH];
// 将盐的字节拷贝到生成的加密口令字节数组的前12个字节以便在验证口令时取出盐
System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);
// 将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节
System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);
// 将字节数组格式加密后的口令转化为16进制字符串格式的口令
return byteToHexString(pwd);
}catch (Exception exception){
log.info("md5加密失败[{}]", str, exception);
return str;
}
}
}

View File

@ -1,5 +1,6 @@
package com.muyu.vehicle;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.common.SystemConstant;
import com.muyu.common.ThreadPool;
import com.muyu.domain.Vehicle;
@ -139,7 +140,8 @@ public class VehicleInstance {
options.setKeepAliveInterval(60);
// 连接
client.connect(options);
log.info("车辆:[{}] 客户端初始化成功", getVin());
log.info("车辆:[{}] 客户端初始化成功连接配置:{}", getVin(),
JSONObject.toJSONString(this.mqttProperties));
} catch (MqttException e) {
log.error("车辆:[{}] 客户端初始化异常", getVin(), e);
}

View File

@ -0,0 +1,21 @@
package com.muyu.vehicle.api;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.JSONBody;
import com.dtflys.forest.annotation.Post;
import com.muyu.common.Result;
import com.muyu.vehicle.api.req.VehicleConnectionReq;
/**
* @author DongZl
* @description:
* @Date 2023-11-28 10:20
*/
@BaseRequest(
baseURL = "${adminHost}"
)
public interface ClientAdmin {
@Post("${adminTopicUri}")
public Result<String> vehicleConnection(@JSONBody VehicleConnectionReq vehicleConnectionReq);
}

View File

@ -0,0 +1,51 @@
package com.muyu.vehicle.api.req;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author DongZl
* @description:
* @Date 2023-11-28 10:32
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VehicleConnectionReq {
/**
* {
* "vehicleVin": "VIN1234567894",
* "timestamp": "11111",
* "username": "你好",
* "nonce": "33"
* }
*/
/**
* vin
*/
@JSONField(name = "vehicleVin")
private String vin;
/**
*
*/
private String timestamp;
/**
*
*/
@JSONField(name = "username")
private String userName;
/**
*
*/
private String nonce;
}

View File

@ -68,4 +68,19 @@ logging:
pattern:
file: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n'
console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n'
# http调用框架
forest:
max-connections: 1000 # 连接池最大连接数
connect-timeout: 3000 # 连接超时时间,单位为毫秒
read-timeout: 3000 # 数据读取超时时间,单位为毫秒
variables:
adminHost: ${mqtt.admin.host}
adminTopicUri: ${mqtt.admin.topic-uri}
# 服务器配置
mqtt:
server:
host: tcp://47.99.149.28:1883
admin:
host: http://47.120.48.139:9000
topic-uri: /verify/vehicleConnection

View File

@ -0,0 +1,34 @@
package com;
import com.muyu.VehicleSimulationApplication;
import com.muyu.common.Result;
import com.muyu.vehicle.api.ClientAdmin;
import com.muyu.vehicle.api.req.VehicleConnectionReq;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author DongZl
* @description:
* @Date 2023-11-28 10:36
*/
@SpringBootTest(classes = VehicleSimulationApplication.class)
public class AdminTest {
@Autowired
private ClientAdmin clientAdmin;
@Test
public void vehicleConnTest(){
Result<String> result = clientAdmin.vehicleConnection(
VehicleConnectionReq.builder()
.vin("VIN1234567894")
.timestamp(String.valueOf(System.currentTimeMillis()))
.userName("156841600")
.nonce("134812")
.build()
);
System.out.println(result);
}
}