import logging import socket import threading from unittest import case from models.msg import Msg class TcpSer(threading.Thread): # 定义服务器地址和端口 HOST = '127.0.0.1' PORT = 2230 def __init__(self,host,port): super().__init__() self.HOST=host self.PORT=port self.connected_clients=[] # 消费者 self.consumers=[] self.lock = threading.Lock() # 处理客户端连接的函数 def handle_client(self,client_socket): try: # 当客户端连接时,将其添加到列表中 self.connected_clients.append(client_socket) print(f"新连接: {client_socket.getpeername()}") # 保持连接,直到客户端断开 while True: # 接收客户端数据(如果需要) data = client_socket.recv(4096) msg_str=data.decode('utf-8') if not data: break # 如果没有数据,退出循环 print(f"从 {client_socket.getpeername()} 收到: {msg_str}") # 反序列化为 实例 s_cmd = Msg.from_json(msg_str) valid_msg:bool=True match s_cmd.cmd: case "getPoints" | "setPoints": self.on_data(s_cmd,valid_msg) case "videoFps"| "dataFps": self.on_data(s_cmd,valid_msg) case "setCap": self.on_data(s_cmd,valid_msg) # todo 添加处理 case _: valid_msg = False err_msg=f"valid cmd={s_cmd.cmd}" resp=f"""{{"_from": "dev","cmd": "{s_cmd.cmd}","values": {{"operate": false,"err": "{err_msg}"}}}}""" client_socket.sendall(resp.encode()) print("非法命令",resp) print("通讯完成") except Exception as e: print(f"处理客户端时出错: {e}") finally: # 从列表中移除客户端并关闭连接 if client_socket in self.connected_clients: self.connected_clients.remove(client_socket) print(f"连接关闭: {client_socket.getpeername()}") client_socket.close() # 注册的消费者必须携带on_data 方法 def add_subscribe(self,consumer): if hasattr(consumer, 'on_data'): print(f"加入 consumer {consumer} ") self.consumers.append(consumer) else: print("consumer 缺少on_data函数,订阅无效 ") def on_data(self,msg,valid): for consumer in self.consumers: try: resp=consumer.on_data(msg) self.broadcast_message(resp) except Exception as e: logging.warn("通讯异常",e) # 广播消息给所有连接的客户端 def broadcast_message(self,message:str): with self.lock: if len(message)==0: return message+="\n\n" for client in self.connected_clients: try: client.sendall(message.encode()) except Exception as e: print(f"向客户端发送消息时出错: {e}") # 如果发送失败,从列表中移除客户端 if client in self.connected_clients: self.connected_clients.remove(client) client.close() def run(self): # 创建服务器套接字 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: server_socket.bind((self.HOST,self.PORT)) server_socket.listen() print(f"服务器监听在 {self.HOST}:{self.PORT}...") try: # 保持服务器运行并接受新的连接 while True: client_socket, addr = server_socket.accept() print(f"连接来自 {addr}") # 为每个客户端启动一个线程 client_thread = threading.Thread(target=self.handle_client, args=(client_socket,)) client_thread.daemon = True # 守护线程,服务器关闭时自动结束 client_thread.start() except KeyboardInterrupt: print("服务器关闭...") finally: # 关闭所有客户端连接 for client in self.connected_clients: client.close() server_socket.close() if __name__ == '__main__': tcp=TcpSer("127.0.0.1",2230) tcp.run()