85 lines
2.7 KiB
Python
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()
|