🎨 优化连接稳定性

This commit is contained in:
Wuyi无疑 2023-04-16 19:47:21 +08:00
parent 5c14c3800e
commit 2ebab890af
2 changed files with 28 additions and 5 deletions

View File

@ -1,6 +1,7 @@
from typing import List, Literal, Optional from typing import List, Literal, Optional
from hoshino import priv from hoshino import priv
from websockets.exceptions import ConnectionClosed
from hoshino.typing import CQEvent, HoshinoBot, NoticeSession from hoshino.typing import CQEvent, HoshinoBot, NoticeSession
from .client import GsClient from .client import GsClient
@ -15,14 +16,19 @@ async def connect():
global gsclient global gsclient
try: try:
gsclient = await GsClient().async_connect() gsclient = await GsClient().async_connect()
await gsclient.start()
except ConnectionRefusedError: except ConnectionRefusedError:
logger.error('Core服务器连接失败...请稍后使用[启动core]命令启动...') logger.error('Core服务器连接失败...请稍后使用[启动core]命令启动...')
async def get_gs_msg(ev): async def get_gs_msg(ev):
if gsclient is None or not gsclient.is_alive: if gsclient is None:
return await connect() return await connect()
try:
await gsclient.ws.ping()
except ConnectionClosed:
return await connect()
# 通用字段获取 # 通用字段获取
user_id = str(ev.user_id) user_id = str(ev.user_id)
msg_id = str(ev.message_id) msg_id = str(ev.message_id)

View File

@ -17,6 +17,8 @@ bots: Dict[str, str] = {}
class GsClient: class GsClient:
_instance = None
@classmethod @classmethod
async def async_connect( async def async_connect(
cls, IP: str = 'localhost', PORT: Union[str, int] = '8765' cls, IP: str = 'localhost', PORT: Union[str, int] = '8765'
@ -30,8 +32,16 @@ class GsClient:
) )
logger.info(f'与[gsuid-core]成功连接! Bot_ID: {BOT_ID}') logger.info(f'与[gsuid-core]成功连接! Bot_ID: {BOT_ID}')
cls.msg_list = asyncio.queues.Queue() cls.msg_list = asyncio.queues.Queue()
cls.pending = []
await self.start()
return self return self
def __new__(cls, *args, **kwargs):
# 判断sv是否已经被初始化
if cls._instance is None:
cls._instance = super(GsClient, cls).__new__(cls, *args, **kwargs)
return cls._instance
async def recv_msg(self): async def recv_msg(self):
try: try:
global bots global bots
@ -100,8 +110,17 @@ class GsClient:
except RuntimeError: except RuntimeError:
pass pass
except ConnectionClosedError: except ConnectionClosedError:
for task in self.pending:
task.cancel()
logger.warning(f'与[gsuid-core]断开连接! Bot_ID: {BOT_ID}') logger.warning(f'与[gsuid-core]断开连接! Bot_ID: {BOT_ID}')
self.is_alive = False self.is_alive = False
for _ in range(30):
await asyncio.sleep(5)
try:
await self.async_connect()
break
except: # noqa
logger.debug('自动连接core服务器失败...五秒后重新连接...')
async def _input(self, msg: MessageReceive): async def _input(self, msg: MessageReceive):
await self.msg_list.put(msg) await self.msg_list.put(msg)
@ -115,12 +134,10 @@ class GsClient:
async def start(self): async def start(self):
recv_task = asyncio.create_task(self.recv_msg()) recv_task = asyncio.create_task(self.recv_msg())
send_task = asyncio.create_task(self.send_msg()) send_task = asyncio.create_task(self.send_msg())
_, pending = await asyncio.wait( _, self.pending = await asyncio.wait(
[recv_task, send_task], [recv_task, send_task],
return_when=asyncio.FIRST_COMPLETED, return_when=asyncio.FIRST_COMPLETED,
) )
for task in pending:
task.cancel()
def to_json(msg: str, name: str, uin: int): def to_json(msg: str, name: str, uin: int):