Compare commits
3 Commits
0cfd659bd8
...
cea43d282c
| Author | SHA1 | Date | |
|---|---|---|---|
| cea43d282c | |||
| 200a505394 | |||
| 69a9a912da |
@@ -211,7 +211,8 @@ services:
|
|||||||
SPRING_DATA_REDIS_PASSWORD: "9kHXcZ1ojFsD"
|
SPRING_DATA_REDIS_PASSWORD: "9kHXcZ1ojFsD"
|
||||||
|
|
||||||
ROCKETMQ_NAME_SERVER: 172.17.16.14:9876
|
ROCKETMQ_NAME_SERVER: 172.17.16.14:9876
|
||||||
|
# 添加这一行
|
||||||
|
VIEWSH_IOT_GATEWAY_RPC_URL: "http://aiot-iot-server:48091"
|
||||||
volumes:
|
volumes:
|
||||||
- app-logs:/app/logs
|
- app-logs:/app/logs
|
||||||
deploy:
|
deploy:
|
||||||
|
|||||||
@@ -38,26 +38,23 @@ public class Jt808ProtocolUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
// 写入起始部分
|
// 只处理 start 到 end 范围内的数据(不包含 start 之前和 end 之后的数据)
|
||||||
for (int i = 0; i < start; i++) {
|
// 这样返回的数组就是纯净的、去除了首尾标识符且已反转义的数据包
|
||||||
baos.write(bs[i]);
|
for (int i = start; i < end; i++) {
|
||||||
}
|
if (bs[i] == 0x7d && i + 1 < end) { // 确保 i+1 不越界
|
||||||
// 处理需要反转义的部分
|
if (bs[i + 1] == 0x01) {
|
||||||
for (int i = start; i < end - 1; i++) {
|
baos.write(0x7d);
|
||||||
if (bs[i] == 0x7d && bs[i + 1] == 0x01) {
|
i++;
|
||||||
baos.write(0x7d);
|
} else if (bs[i + 1] == 0x02) {
|
||||||
i++;
|
baos.write(0x7e);
|
||||||
} else if (bs[i] == 0x7d && bs[i + 1] == 0x02) {
|
i++;
|
||||||
baos.write(0x7e);
|
} else {
|
||||||
i++;
|
baos.write(bs[i]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
baos.write(bs[i]);
|
baos.write(bs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 写入结束部分
|
|
||||||
for (int i = end - 1; i < bs.length; i++) {
|
|
||||||
baos.write(bs[i]);
|
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,13 +139,50 @@ public class IotTcpUpstreamHandler implements Handler<NetSocket> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 判断是否为认证消息
|
// 5. 判断是否为认证消息
|
||||||
if (isAuthenticationMessage(message)) {
|
if (isAuthenticationMessage(message)) {
|
||||||
handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler);
|
handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler);
|
||||||
} else {
|
} else {
|
||||||
handleBusinessWithProtocol(clientId, message, codecType, socket, handler);
|
// 针对 JT808 协议的特殊处理:如果是位置上报(thing.property.post)且包含身份信息(手机号),尝试自动注册
|
||||||
}
|
// 这可以解决设备重启后未注册就发送数据的问题,或者简化认证流程
|
||||||
}
|
if (CODEC_TYPE_JT808.equals(codecType)) {
|
||||||
|
tryAutoRegisterJt808(clientId, message, codecType, socket, handler);
|
||||||
|
} else {
|
||||||
|
handleBusinessWithProtocol(clientId, message, codecType, socket, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 尝试自动注册 JT808 设备
|
||||||
|
* <p>
|
||||||
|
* JT808 协议中,消息头包含终端手机号。如果设备未认证但发送了有效数据,
|
||||||
|
* 我们可以尝试提取手机号并进行隐式认证,而不是直接断开连接。
|
||||||
|
*/
|
||||||
|
private void tryAutoRegisterJt808(String clientId, IotDeviceMessage message,
|
||||||
|
String codecType, NetSocket socket,
|
||||||
|
ProtocolHandler handler) {
|
||||||
|
// 如果已认证,直接处理业务
|
||||||
|
if (!connectionManager.isNotAuthenticated(socket)) {
|
||||||
|
handleBusinessWithProtocol(clientId, message, codecType, socket, handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[tryAutoRegisterJt808][尝试自动认证 JT808 设备,clientId: {}]", clientId);
|
||||||
|
|
||||||
|
// 使用认证逻辑处理(JT808 协议处理器会提取手机号进行认证)
|
||||||
|
// 这里把业务消息当作认证消息处理,如果协议处理器支持从业务消息提取身份,就能成功
|
||||||
|
// 注意:这依赖于 Jt808ProtocolHandler 的 handleAuthentication 实现能够处理非注册消息
|
||||||
|
handleAuthenticationWithProtocol(clientId, message, codecType, socket, handler);
|
||||||
|
|
||||||
|
// 如果认证成功(handleAuthenticationWithProtocol 内部会注册连接),则继续处理业务消息
|
||||||
|
if (!connectionManager.isNotAuthenticated(socket)) {
|
||||||
|
log.info("[tryAutoRegisterJt808][自动认证成功,继续处理业务消息,clientId: {}]", clientId);
|
||||||
|
handleBusinessWithProtocol(clientId, message, codecType, socket, handler);
|
||||||
|
} else {
|
||||||
|
// 认证依然失败,提示未认证(日志已在 handleAuthenticationWithProtocol 中打印)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用协议处理器处理认证消息
|
* 使用协议处理器处理认证消息
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ viewsh:
|
|||||||
gateway:
|
gateway:
|
||||||
# 设备 RPC 配置
|
# 设备 RPC 配置
|
||||||
rpc:
|
rpc:
|
||||||
url: ${IOT_RPC_URL:http://127.0.0.1:48091}
|
url: ${VIEWSH_GATEWAY_RPC_URL:http://127.0.0.1:48091}
|
||||||
connect-timeout: ${IOT_RPC_CONNECT_TIMEOUT:30s}
|
connect-timeout: ${VIEWSH_RPC_CONNECT_TIMEOUT:30s}
|
||||||
read-timeout: ${IOT_RPC_READ_TIMEOUT:30s}
|
read-timeout: ${VIEWSH_RPC_READ_TIMEOUT:30s}
|
||||||
# 设备 Token 配置
|
# 设备 Token 配置
|
||||||
token:
|
token:
|
||||||
secret: ${IOT_TOKEN_SECRET:viewshIotGatewayTokenSecret123456789}
|
secret: ${VIEWSH_IOT_TOKEN_SECRET:viewshIotGatewayTokenSecret123456789}
|
||||||
expiration: ${IOT_TOKEN_EXPIRATION:7d}
|
expiration: ${VIEWSH_IOT_TOKEN_EXPIRATION:7d}
|
||||||
|
|
||||||
# 协议配置
|
# 协议配置
|
||||||
protocol:
|
protocol:
|
||||||
|
|||||||
Reference in New Issue
Block a user