This commit is contained in:
@@ -50,7 +50,7 @@ public class DeviceController {
|
||||
@PostMapping("/upload")
|
||||
public CommonResult<String> receiveDeviceData(@RequestBody Map<String, Object> payload) {
|
||||
// 广播日志(同时会记录到服务器日志文件)
|
||||
apiLogService.broadcastLog(payload);
|
||||
apiLogService.broadcastLog("API", payload);
|
||||
|
||||
return CommonResult.success("设备数据接收成功");
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@ public class Jt808NettyServer implements CommandLineRunner {
|
||||
@Value("${jt808.port:20048}")
|
||||
private int port;
|
||||
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
private com.hua.transport.jt808.service.ApiLogService apiLogService;
|
||||
|
||||
private TCPServer tcpServer;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("Initializing JT808 TCP Server on port: {}", port);
|
||||
tcpServer = new TCPServer(port);
|
||||
tcpServer = new TCPServer(port, apiLogService);
|
||||
tcpServer.startServer();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,14 @@ import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import io.netty.util.concurrent.Future;
|
||||
|
||||
import com.hua.transport.jt808.service.ApiLogService;
|
||||
|
||||
public class TCPServer {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private int port;
|
||||
private ApiLogService apiLogService;
|
||||
private EventLoopGroup bossGroup = null;
|
||||
private EventLoopGroup workerGroup = null;
|
||||
private volatile boolean isRunning = false;
|
||||
@@ -32,9 +35,10 @@ public class TCPServer {
|
||||
public TCPServer() {
|
||||
}
|
||||
|
||||
public TCPServer(int port) {
|
||||
public TCPServer(int port, ApiLogService apiLogService) {
|
||||
this();
|
||||
this.port = port;
|
||||
this.apiLogService = apiLogService;
|
||||
}
|
||||
|
||||
private void bind() throws Exception {
|
||||
@@ -58,7 +62,7 @@ public class TCPServer {
|
||||
Unpooled.copiedBuffer(new byte[] { 0x7e, 0x7e })));
|
||||
//ch.pipeline().addLast(new PackageDataDecoder());
|
||||
|
||||
ch.pipeline().addLast(new TCPServerHandler());
|
||||
ch.pipeline().addLast(new TCPServerHandler(apiLogService));
|
||||
}
|
||||
}).option(ChannelOption.SO_BACKLOG, 128) //
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true);
|
||||
|
||||
@@ -25,14 +25,20 @@ public class ApiLogService {
|
||||
return emitter;
|
||||
}
|
||||
|
||||
public void broadcastLog(Map<String, Object> payload) {
|
||||
public void broadcastLog(String source, Map<String, Object> payload) {
|
||||
// Log to server file
|
||||
log.info("【API Data Received】: {}", payload);
|
||||
log.info("【{} Data Received】: {}", source, payload);
|
||||
|
||||
// Add source to payload
|
||||
// Create a new map to avoid modifying the original payload if it's used elsewhere
|
||||
Map<String, Object> message = new java.util.HashMap<>(payload);
|
||||
message.put("source", source);
|
||||
message.put("timestamp", System.currentTimeMillis());
|
||||
|
||||
// Broadcast to Web UI
|
||||
for (SseEmitter emitter : emitters) {
|
||||
try {
|
||||
emitter.send(SseEmitter.event().name("api-log").data(payload));
|
||||
emitter.send(SseEmitter.event().name("log-event").data(message));
|
||||
} catch (IOException e) {
|
||||
emitters.remove(emitter);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,23 @@ import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
import com.hua.transport.jt808.service.ApiLogService;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1)
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final DataDecoder decoder;
|
||||
private final SessionManager sessionManager;
|
||||
private final ApiLogService apiLogService;
|
||||
|
||||
|
||||
public TCPServerHandler() {
|
||||
public TCPServerHandler(ApiLogService apiLogService) {
|
||||
this.decoder = new DataDecoder();
|
||||
this.sessionManager = SessionManager.getInstance();
|
||||
this.apiLogService = apiLogService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,6 +50,18 @@ public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1)
|
||||
Integer msgId = header.getId();
|
||||
|
||||
logger.info("消息头部:msgid={}, phone={}, flowid={}", msgId, header.getTerminalPhone(), header.getFlowId());
|
||||
|
||||
// Broadcast to UI
|
||||
if (apiLogService != null) {
|
||||
Map<String, Object> logMap = new HashMap<>();
|
||||
logMap.put("msgId", String.format("0x%04x", msgId));
|
||||
logMap.put("phone", header.getTerminalPhone());
|
||||
logMap.put("flowId", header.getFlowId());
|
||||
logMap.put("summary", "TCP Message Received");
|
||||
// Add raw object if needed, or string representation
|
||||
logMap.put("details", packageData.toString());
|
||||
apiLogService.broadcastLog("TCP", logMap);
|
||||
}
|
||||
|
||||
MessageHandler handler = MessageHandlerFactory.getInstance(msgId);
|
||||
if(handler != null){
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<div v-if="logs.length === 0" class="text-muted text-center mt-5">Waiting for data...</div>
|
||||
<div v-for="(log, index) in logs" :key="index" class="log-entry">
|
||||
<span class="log-time">[{{ log.time }}]</span>
|
||||
<span class="badge me-2" :class="log.source === 'TCP' ? 'bg-warning text-dark' : 'bg-success'">{{ log.source }}</span>
|
||||
<span>{{ log.data }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -140,16 +141,23 @@
|
||||
setTimeout(() => this.connectSSE(), 3000);
|
||||
};
|
||||
|
||||
this.eventSource.addEventListener('api-log', (event) => {
|
||||
this.eventSource.addEventListener('log-event', (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
this.addLog(data);
|
||||
});
|
||||
},
|
||||
addLog(data) {
|
||||
const now = new Date().toLocaleTimeString();
|
||||
const source = data.source || 'INFO';
|
||||
// Remove source/timestamp from display data to avoid clutter if desired, or just show all
|
||||
const displayData = { ...data };
|
||||
delete displayData.source;
|
||||
delete displayData.timestamp;
|
||||
|
||||
this.logs.unshift({
|
||||
time: now,
|
||||
data: typeof data === 'string' ? data : JSON.stringify(data)
|
||||
source: source,
|
||||
data: JSON.stringify(displayData)
|
||||
});
|
||||
// Keep last 50 logs
|
||||
if (this.logs.length > 50) this.logs.pop();
|
||||
|
||||
Reference in New Issue
Block a user