优化微信同步超时兜底并下沉头像缓存预热
- 为 Msg/Sync 增加超时异常与主循环重试保护,避免启动阶段超时直接退出\n- 新增联系人头像缓存系统定时任务,启动时不再主动批量下载头像\n- 保留头像按需补下载能力,并补充详细中文注释
This commit is contained in:
@@ -18,6 +18,7 @@ import aiofiles
|
||||
from utils.video_utils import get_first_frame, get_first_frame_bytes
|
||||
from utils.trace_context import format_trace_prefix
|
||||
from wechat_ipad import UserLoggedOut
|
||||
from wechat_ipad.errors import RequestTimeoutError
|
||||
from wechat_ipad.client.base import WechatAPIClientBase
|
||||
|
||||
|
||||
@@ -731,15 +732,41 @@ class MessageMixin(WechatAPIClientBase):
|
||||
|
||||
Raises:
|
||||
UserLoggedOut: 未登录时调用
|
||||
RequestTimeoutError: 同步接口超时时抛出,方便上层做重试而不是直接退出主循环
|
||||
根据error_handler处理错误
|
||||
"""
|
||||
if not self.wxid:
|
||||
raise UserLoggedOut("请先登录")
|
||||
|
||||
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=10)) as session:
|
||||
# `/api/Msg/Sync` 在没有新消息时,服务端经常会把请求挂住一段时间再返回,
|
||||
# 行为更接近“短轮询/长轮询”而不是普通的即时 RPC。
|
||||
# 因此这里不能继续沿用 10 秒总超时,否则在空闲期也会被误判成异常。
|
||||
timeout = aiohttp.ClientTimeout(
|
||||
total=70,
|
||||
connect=10,
|
||||
sock_connect=10,
|
||||
sock_read=60,
|
||||
)
|
||||
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||
json_param = {"Wxid": self.wxid, "Scene": 0, "Synckey": ""}
|
||||
response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/Sync', json=json_param)
|
||||
json_resp = await response.json()
|
||||
try:
|
||||
response = await session.post(f'http://{self.ip}:{self.port}/api/Msg/Sync', json=json_param)
|
||||
# 某些服务端实现不会稳定返回 `application/json`,
|
||||
# 这里放宽 content-type 校验,避免把“已收到响应”误判成解析失败。
|
||||
json_resp = await response.json(content_type=None)
|
||||
except asyncio.TimeoutError as exc:
|
||||
self.logging.warning(
|
||||
"同步消息超时: wxid:{} server={}:{} connect_timeout={}s read_timeout={}s total_timeout={}s",
|
||||
self.wxid,
|
||||
self.ip,
|
||||
self.port,
|
||||
timeout.sock_connect,
|
||||
timeout.sock_read,
|
||||
timeout.total,
|
||||
)
|
||||
raise RequestTimeoutError(
|
||||
f"SyncMessage 接口调用超时,读超时={timeout.sock_read}s,总超时={timeout.total}s"
|
||||
) from exc
|
||||
|
||||
if json_resp.get("Success"):
|
||||
return json_resp.get("Data")
|
||||
|
||||
Reference in New Issue
Block a user