车辆上线动态获取主题,代码对接完成
parent
8413e2e627
commit
7fd2e3481e
14
pom.xml
14
pom.xml
|
@ -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>
|
||||
|
|
|
@ -23,11 +23,6 @@ public interface VehicleInstanceService {
|
|||
*/
|
||||
public void init(Vehicle vehicle);
|
||||
|
||||
/**
|
||||
* 初始化链接客户端
|
||||
* @param vin 车辆VIN
|
||||
*/
|
||||
public void initClient(String vin);
|
||||
|
||||
/**
|
||||
* 车辆结果对象
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 将指定byte数组转换成16进制字符串
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue