从服务器读取IP并将检测数据写入数据库
This commit is contained in:
35
ws/ws.py
35
ws/ws.py
@ -33,7 +33,7 @@ def get_current_time_file_str() -> str:
|
||||
class ClientConnection:
|
||||
def __init__(self, websocket: WebSocket, client_ip: str):
|
||||
self.websocket = websocket
|
||||
self.client_ip = client_ip
|
||||
self.client_ip = client_ip # 已初始化客户端IP,用于传递给detect
|
||||
self.last_heartbeat = datetime.datetime.now()
|
||||
self.frame_queue = asyncio.Queue(maxsize=FRAME_QUEUE_SIZE)
|
||||
self.consumer_task: Optional[asyncio.Task] = None
|
||||
@ -84,7 +84,7 @@ class ClientConnection:
|
||||
print(f"[{get_current_time_str()}] 客户端{self.client_ip}: 帧消费逻辑错误 - {str(e)}")
|
||||
|
||||
async def process_frame(self, frame_data: bytes) -> None:
|
||||
"""处理单帧图像数据(核心修复:按3个返回值解包)"""
|
||||
"""处理单帧图像数据(核心修改:detect函数传入 client_ip + img 双参数)"""
|
||||
# 二进制转OpenCV图像
|
||||
nparr = np.frombuffer(frame_data, np.uint8)
|
||||
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
|
||||
@ -93,19 +93,21 @@ class ClientConnection:
|
||||
return
|
||||
|
||||
try:
|
||||
# -------------------------- 修复核心:匹配detect返回的3个值 --------------------------
|
||||
# 假设detect返回 (是否违规, 结果数据, 检测器类型)
|
||||
# -------------------------- 核心修改:按要求传入参数(1.client_ip 2.img) --------------------------
|
||||
# detect函数参数顺序:第一个为client_ip,第二个为图像数据img
|
||||
# 保持返回值解包(是否违规, 结果数据, 检测器类型)不变
|
||||
has_violation, data, detector_type = await asyncio.to_thread(
|
||||
detect, # 调用检测函数
|
||||
img # 传入图像参数
|
||||
detect, # 调用检测函数
|
||||
self.client_ip, # 第一个参数:客户端IP(新增,按需求顺序)
|
||||
img # 第二个参数:图像数据(原参数,调整顺序)
|
||||
)
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
# 打印检测结果(移除task_id相关内容)
|
||||
# 打印检测结果(包含客户端IP,与传入参数对应)
|
||||
print(f"[{get_current_time_str()}] 客户端{self.client_ip}: 检测结果 - "
|
||||
f"违规: {has_violation}, 类型: {detector_type}, 数据: {data}")
|
||||
|
||||
# 处理违规逻辑
|
||||
# 处理违规逻辑(逻辑不变,基于detect返回结果执行)
|
||||
if has_violation:
|
||||
print(f"[{get_current_time_str()}] 客户端{self.client_ip}: 检测到违规 - "
|
||||
f"类型: {detector_type}, 详情: {data}")
|
||||
@ -227,7 +229,7 @@ ws_router = APIRouter()
|
||||
|
||||
@ws_router.websocket(WS_ENDPOINT)
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
load_model()
|
||||
load_model() # 加载检测模型(仅在连接建立时加载一次,避免重复加载)
|
||||
await websocket.accept()
|
||||
client_ip = websocket.client.host if websocket.client else "unknown_ip"
|
||||
current_time = get_current_time_str()
|
||||
@ -236,7 +238,7 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
is_online_updated = False
|
||||
|
||||
try:
|
||||
# 处理重复连接
|
||||
# 处理重复连接(同一IP断开旧连接)
|
||||
if client_ip in connected_clients:
|
||||
old_conn = connected_clients[client_ip]
|
||||
if old_conn.consumer_task and not old_conn.consumer_task.done():
|
||||
@ -245,13 +247,13 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
connected_clients.pop(client_ip)
|
||||
print(f"[{current_time}] 客户端{client_ip}: 已关闭旧连接")
|
||||
|
||||
# 注册新连接
|
||||
# 注册新连接(绑定client_ip和WebSocket)
|
||||
new_conn = ClientConnection(websocket, client_ip)
|
||||
connected_clients[client_ip] = new_conn
|
||||
new_conn.start_consumer()
|
||||
await new_conn.send_frame_permit()
|
||||
new_conn.start_consumer() # 启动帧消费任务
|
||||
await new_conn.send_frame_permit() # 发送首次帧许可
|
||||
|
||||
# 标记上线
|
||||
# 标记客户端上线
|
||||
try:
|
||||
await asyncio.to_thread(update_online_status_by_ip, client_ip, 1)
|
||||
action_data = DeviceActionCreate(client_ip=client_ip, action=1)
|
||||
@ -263,7 +265,7 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
|
||||
print(f"[{current_time}] 客户端{client_ip}: 新连接注册成功、在线数: {len(connected_clients)}")
|
||||
|
||||
# 消息循环
|
||||
# 消息循环(持续接收客户端消息)
|
||||
while True:
|
||||
data = await websocket.receive()
|
||||
if "text" in data:
|
||||
@ -276,12 +278,13 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
except Exception as e:
|
||||
print(f"[{get_current_time_str()}] 客户端{client_ip}: 连接异常 - {str(e)[:50]}")
|
||||
finally:
|
||||
# 清理资源
|
||||
# 清理资源(断开后标记离线+删除连接)
|
||||
if client_ip in connected_clients:
|
||||
conn = connected_clients[client_ip]
|
||||
if conn.consumer_task and not conn.consumer_task.done():
|
||||
conn.consumer_task.cancel()
|
||||
|
||||
# 仅当上线状态更新成功时,才执行离线更新
|
||||
if is_online_updated:
|
||||
try:
|
||||
await asyncio.to_thread(update_online_status_by_ip, client_ip, 0)
|
||||
|
Reference in New Issue
Block a user