更新
This commit is contained in:
@@ -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 常见)
|
||||
|
||||
Reference in New Issue
Block a user