车辆上线动态获取主题,代码对接完成
parent
8413e2e627
commit
7fd2e3481e
14
pom.xml
14
pom.xml
|
@ -75,6 +75,20 @@
|
||||||
<artifactId>fastjson2</artifactId>
|
<artifactId>fastjson2</artifactId>
|
||||||
<version>2.0.42</version>
|
<version>2.0.42</version>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -23,11 +23,6 @@ public interface VehicleInstanceService {
|
||||||
*/
|
*/
|
||||||
public void init(Vehicle vehicle);
|
public void init(Vehicle vehicle);
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化链接客户端
|
|
||||||
* @param vin 车辆VIN
|
|
||||||
*/
|
|
||||||
public void initClient(String vin);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 车辆结果对象
|
* 车辆结果对象
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.muyu.service.impl;
|
package com.muyu.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.muyu.common.Result;
|
||||||
import com.muyu.domain.PositionRouteInfo;
|
|
||||||
import com.muyu.domain.Vehicle;
|
import com.muyu.domain.Vehicle;
|
||||||
import com.muyu.domain.model.PositionModel;
|
import com.muyu.domain.model.PositionModel;
|
||||||
import com.muyu.domain.req.CheckPositionReq;
|
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.domain.resp.VehicleInstanceResp;
|
||||||
import com.muyu.service.PositionRouteService;
|
import com.muyu.service.PositionRouteService;
|
||||||
import com.muyu.service.VehicleInstanceService;
|
import com.muyu.service.VehicleInstanceService;
|
||||||
|
import com.muyu.utils.MD5Util;
|
||||||
import com.muyu.vehicle.VehicleInstance;
|
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.core.LocalContainer;
|
||||||
import com.muyu.vehicle.model.VehicleData;
|
import com.muyu.vehicle.model.VehicleData;
|
||||||
import com.muyu.vehicle.model.properties.MqttProperties;
|
import com.muyu.vehicle.model.properties.MqttProperties;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author DongZeLiang
|
* @author DongZeLiang
|
||||||
|
@ -35,6 +38,12 @@ public class VehicleInstanceServiceImpl implements VehicleInstanceService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PositionRouteService positionRouteService;
|
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());
|
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){
|
if (vehicleInstance == null){
|
||||||
throw new RuntimeException("没有【"+vin+"】车辆");
|
throw new RuntimeException("没有【"+vin+"】车辆");
|
||||||
}
|
}
|
||||||
vehicleInstance.setMqttProperties(
|
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||||
MqttProperties.builder()
|
VehicleConnectionReq connectionReq = VehicleConnectionReq.builder()
|
||||||
.broker("tcp://fluxmq.muyu.icu:1883")
|
.vin(vin)
|
||||||
.topic("test")
|
.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)
|
.clientId(vin)
|
||||||
.build()
|
.username(connectionReq.getUserName())
|
||||||
);
|
.password(vin+connectionReq.getTimestamp()+connectionReq.getNonce())
|
||||||
|
.build();
|
||||||
|
vehicleInstance.setMqttProperties(mqttProperties);
|
||||||
vehicleInstance.initClient();
|
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;
|
package com.muyu.vehicle;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.muyu.common.SystemConstant;
|
import com.muyu.common.SystemConstant;
|
||||||
import com.muyu.common.ThreadPool;
|
import com.muyu.common.ThreadPool;
|
||||||
import com.muyu.domain.Vehicle;
|
import com.muyu.domain.Vehicle;
|
||||||
|
@ -139,7 +140,8 @@ public class VehicleInstance {
|
||||||
options.setKeepAliveInterval(60);
|
options.setKeepAliveInterval(60);
|
||||||
// 连接
|
// 连接
|
||||||
client.connect(options);
|
client.connect(options);
|
||||||
log.info("车辆:[{}] 客户端初始化成功", getVin());
|
log.info("车辆:[{}] 客户端初始化成功连接配置:{}", getVin(),
|
||||||
|
JSONObject.toJSONString(this.mqttProperties));
|
||||||
} catch (MqttException e) {
|
} catch (MqttException e) {
|
||||||
log.error("车辆:[{}] 客户端初始化异常", getVin(), 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:
|
pattern:
|
||||||
file: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n'
|
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'
|
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