fix: 修复 HeartBeat 大小写不匹配导致交互未被记录的问题
根本原因: 设备发送 Method='HeartBeat'(大写B), 代码匹配'Heartbeat'(小写b),
心跳包被静默忽略, record_interaction 未调用, 导致监控误判为离线。
修复:
- UDP/TCP 方法匹配改为 case-insensitive (method_lower)
- handle_timestamp 增加 record_interaction 调用 (TimeStamp 也是设备交互)
- TCP 连接/断开时写入 tb_device_log 事件日志 (tcp_connect/tcp_disconnect)
This commit is contained in:
@@ -187,21 +187,11 @@ async def handle_heartbeat(data: dict) -> str | None:
|
|||||||
|
|
||||||
|
|
||||||
def handle_timestamp(data: dict) -> str:
|
def handle_timestamp(data: dict) -> str:
|
||||||
"""处理时间同步请求
|
"""处理时间同步请求(也是设备交互)"""
|
||||||
|
|
||||||
TimeStamp 请求格式:
|
|
||||||
{
|
|
||||||
"Method": "TimeStamp",
|
|
||||||
"Params": {
|
|
||||||
"Device_id": "2345",
|
|
||||||
"TimeZone": "Asia/Shanghai"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
返回格式参考 PGLC 协议 3.5 节。
|
|
||||||
"""
|
|
||||||
params = data.get("Params", {})
|
params = data.get("Params", {})
|
||||||
device_id = params.get("Device_id", "")
|
device_id = params.get("Device_id", "")
|
||||||
|
if device_id:
|
||||||
|
record_interaction(device_id)
|
||||||
return make_timestamp_response(device_id, int(time.time()))
|
return make_timestamp_response(device_id, int(time.time()))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ from src.handlers import (
|
|||||||
device_status_monitor,
|
device_status_monitor,
|
||||||
set_udp_sender,
|
set_udp_sender,
|
||||||
)
|
)
|
||||||
|
from src.models import insert_device_log
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
level=getattr(logging, LOG_LEVEL),
|
level=getattr(logging, LOG_LEVEL),
|
||||||
@@ -75,6 +76,7 @@ class EDCProtocol:
|
|||||||
logger.info(f"UDP {msg} from {addr}")
|
logger.info(f"UDP {msg} from {addr}")
|
||||||
|
|
||||||
method = msg.get("Method", "")
|
method = msg.get("Method", "")
|
||||||
|
method_lower = method.lower()
|
||||||
logger.debug(f"UDP {method} from {addr}")
|
logger.debug(f"UDP {method} from {addr}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -82,11 +84,11 @@ class EDCProtocol:
|
|||||||
if method == "Count_Off":
|
if method == "Count_Off":
|
||||||
# 设备登录上报,只处理不回复
|
# 设备登录上报,只处理不回复
|
||||||
await handle_count_off(msg, addr)
|
await handle_count_off(msg, addr)
|
||||||
elif method == "Heartbeat":
|
elif method_lower == "heartbeat":
|
||||||
response = await handle_heartbeat(msg)
|
response = await handle_heartbeat(msg)
|
||||||
elif method == "TSReport":
|
elif method_lower == "tsreport":
|
||||||
response = await handle_tsreport(msg)
|
response = await handle_tsreport(msg)
|
||||||
elif method == "SerialNet":
|
elif method_lower == "serialnet":
|
||||||
response = await handle_serial_net(msg)
|
response = await handle_serial_net(msg)
|
||||||
|
|
||||||
if response and self.transport:
|
if response and self.transport:
|
||||||
@@ -105,24 +107,36 @@ async def handle_tcp_client(reader: asyncio.StreamReader,
|
|||||||
- 紧凑 JSON (无换行)
|
- 紧凑 JSON (无换行)
|
||||||
"""
|
"""
|
||||||
addr = writer.get_extra_info("peername")
|
addr = writer.get_extra_info("peername")
|
||||||
|
addr_ip = addr[0] if addr else ""
|
||||||
logger.info(f"TCP 连接: {addr}")
|
logger.info(f"TCP 连接: {addr}")
|
||||||
|
|
||||||
|
# TCP 连接事件日志
|
||||||
|
try:
|
||||||
|
asyncio.ensure_future(insert_device_log(
|
||||||
|
serial="", ip=addr_ip,
|
||||||
|
event_type="tcp_connect",
|
||||||
|
content=f"TCP 连接: {addr}",
|
||||||
|
))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
buffer = b""
|
buffer = b""
|
||||||
|
|
||||||
async def process_message(msg: dict):
|
async def process_message(msg: dict):
|
||||||
"""处理单条消息并返回响应文本"""
|
"""处理单条消息并返回响应文本"""
|
||||||
logger.info(f"TCP get_rcv {msg} from {addr}")
|
logger.info(f"TCP get_rcv {msg} from {addr}")
|
||||||
method = msg.get("Method", "")
|
method = msg.get("Method", "")
|
||||||
|
method_lower = method.lower()
|
||||||
logger.debug(f"TCP {method} from {addr}")
|
logger.debug(f"TCP {method} from {addr}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if method == "TimeStamp":
|
if method_lower == "timestamp":
|
||||||
return handle_timestamp(msg)
|
return handle_timestamp(msg)
|
||||||
elif method == "TSReport":
|
elif method_lower == "tsreport":
|
||||||
return await handle_tsreport(msg)
|
return await handle_tsreport(msg)
|
||||||
elif method == "SerialNet":
|
elif method_lower == "serialnet":
|
||||||
return await handle_serial_net(msg)
|
return await handle_serial_net(msg)
|
||||||
elif method == "Heartbeat":
|
elif method_lower == "heartbeat":
|
||||||
return await handle_heartbeat(msg)
|
return await handle_heartbeat(msg)
|
||||||
else:
|
else:
|
||||||
logger.debug(f"TCP 未知方法: {method}")
|
logger.debug(f"TCP 未知方法: {method}")
|
||||||
@@ -176,6 +190,15 @@ async def handle_tcp_client(reader: asyncio.StreamReader,
|
|||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
logger.info(f"TCP 断开: {addr}")
|
logger.info(f"TCP 断开: {addr}")
|
||||||
|
# TCP 断开事件日志
|
||||||
|
try:
|
||||||
|
asyncio.ensure_future(insert_device_log(
|
||||||
|
serial="", ip=addr_ip,
|
||||||
|
event_type="tcp_disconnect",
|
||||||
|
content=f"TCP 断开: {addr}",
|
||||||
|
))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
writer.close()
|
writer.close()
|
||||||
await writer.wait_closed()
|
await writer.wait_closed()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user