Files
tcp-server/endpoint/tcp_server.py
2025-10-26 22:47:13 +08:00

85 lines
2.7 KiB
Python

import asyncio
import signal
import platform
from config.logger_config import logger
from config.setting import settings
from model.index import UNKNOWN_MESSAGE
from processor.tcp_processor import TcpMessageProcessor
class TCPServer:
def __init__(self):
self.host = settings.host
self.port = settings.port
self.server = None
self.clients = set()
self.running = False
self.message_processor = TcpMessageProcessor()
async def handle_client(self, reader, writer):
"""处理客户端连接"""
addr = writer.get_extra_info('peername')
logger.info(f"新客户端连接: {addr}")
self.clients.add(writer)
try:
while self.running:
data = await reader.read(1024)
if not data:
break # 连接断开
message = data.decode('utf-8').strip()
logger.info(f"收到 {addr} 的消息: {message}")
# 放到消息处理器里面处理
response = self.message_processor.process(message)
# 回复消息
if response != UNKNOWN_MESSAGE:
writer.write(response.encode())
await writer.drain()
logger.info(f"回复 {addr}: {response}")
except Exception as e:
logger.error(f"客户端 {addr} 处理错误: {e}")
finally:
if writer in self.clients:
self.clients.remove(writer)
writer.close()
await writer.wait_closed()
logger.warning(f"客户端 {addr} 断开")
async def start(self):
"""启动服务器"""
self.running = True
self.server = await asyncio.start_server(self.handle_client, self.host, self.port)
# 仅在非Windows平台设置信号处理
if platform.system() != 'Windows':
loop = asyncio.get_running_loop()
for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, self.stop)
logger.info(f"TCP服务器已启动 {self.host}:{self.port}")
async with self.server:
await self.server.serve_forever()
async def _safe_stop(self):
"""安全的停止服务器"""
self.running = False
if self.server:
self.server.close()
await self.server.wait_closed()
# 关闭所有客户端连接
for writer in list(self.clients):
writer.close()
await writer.wait_closed()
def stop(self):
"""停止服务器"""
logger.info("正在关闭TCP服务器...")
asyncio.create_task(self._safe_stop())
tcp_server = TCPServer()