This commit is contained in:
Your Name
2026-08-27 18:32:03 +08:00
parent 4ac6990efe
commit 1f3addcf79
50 changed files with 9145 additions and 1760 deletions
+49 -2
View File
@@ -204,9 +204,46 @@ def extract_json_objects(raw: bytes | str) -> list[dict]:
return results
def _looks_like_push_frame(frame) -> bool:
"""判断这段字节确实是 frontier 的 PushFrame 信封。
真实帧一定带 service/method 和 frontier 自己的 headers/traceid;随手一段
二进制偶尔也能被 protobuf 宽松解析成 PushFrame,那种不算。
"""
return bool(
frame.service
or frame.method
or frame.payloadType
or frame.payloadEncoding
or frame.logIdNew
or len(frame.headersList)
)
def _decode_push_frame_payload(frame) -> bytes:
"""取出 PushFrame 内层负载,按 payloadEncoding 解压。
frontier 会用 gzip 压缩 payload;直接把压缩字节喂给 Response.ParseFromString
只会抛异常并被吞掉,整条私信就此丢失。
"""
body = bytes(frame.payload or b"")
if not body:
return b""
encoding = str(frame.payloadEncoding or "").lower()
if encoding in ("gzip", "gz"):
try:
return gzip.decompress(body)
except Exception as exc:
logger.warning("Failed to gunzip frontier frame payload: %s", exc)
return body
return body
def parse_ws_payload(raw: bytes | str) -> list[dict]:
"""解析 WebSocket 二进制帧,返回标准化消息 dict 列表"""
messages = []
frame_payload = b""
is_push_frame = False
# 尝试 Protobuf 解包
if isinstance(raw, bytes):
@@ -214,9 +251,14 @@ def parse_ws_payload(raw: bytes | str) -> list[dict]:
from .static import Live_pb2, Response_pb2
frame = Live_pb2.PushFrame()
frame.ParseFromString(raw)
if frame.payloadType == 'pb':
is_push_frame = _looks_like_push_frame(frame)
frame_payload = _decode_push_frame_payload(frame)
# payloadType 不再作为判据:现网 frontier 帧会带 'pb'、'text/json'
# 或空值,之前只认 'pb' 会把其余帧整帧丢弃。真正的判据是解出来
# 有没有 new_message_notify;解不出就照旧走下面的 JSON/文本兜底。
if frame_payload:
response = Response_pb2.Response()
response.ParseFromString(frame.payload)
response.ParseFromString(frame_payload)
body = response.body
if body.HasField("new_message_notify"):
notify = body.new_message_notify
@@ -306,6 +348,11 @@ def parse_ws_payload(raw: bytes | str) -> list[dict]:
if isinstance(raw, str):
payloads = [raw.encode("utf-8", errors="ignore")]
elif is_push_frame:
# 已确认是 frontier PushFrame:只解析它的内层负载。整帧字节里还有
# seqId / traceid / payloadType 等元数据,拿去做纯文本兜底会把每条
# 「连接建立」等控制帧误当成一条用户私信记录并触发一次自动回复。
payloads = [frame_payload] if frame_payload else []
else:
payloads = [raw]
# 尝试 gzip 解压(frontier 常见)