Files
zhidian/client/wire.py
T
2026-10-22 09:07:39 +08:00

66 lines
1.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
wire.py — 会话消息的打包 / 解包。
pynng 一条消息只能是单块二进制,所以这里做一层很简单的外壳:
b"LS01" | u32 头长度 | JSON 头(UTF-8) | 二进制体
每个头里都带 session:
{
"id": "<一次运行一个 uuid>",
"client_ip": "192.168.43.23", # 电脑自己的地址
"board_ip": "192.168.43.50", # 板子的地址
"started_ns": 1712345678901234567,
"note": "..."
}
这样每一条请求和应答都能看出属于哪个会话、从哪台机器来。
"""
import json
import struct
import time
import uuid
MAGIC = b"LS01"
_LEN = struct.Struct("<I")
def new_session(board_ip, client_ip, note=""):
"""新建一个会话(电脑端每次启动调一次)。"""
return {
"id": uuid.uuid4().hex,
"client_ip": str(client_ip),
"board_ip": str(board_ip),
"started_ns": time.time_ns(),
"note": str(note),
}
def pack(header, blob=b""):
"""dict + 二进制体 -> bytes。"""
h = json.dumps(header, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
return MAGIC + _LEN.pack(len(h)) + h + bytes(blob)
def unpack(data):
"""bytes -> (dict, 二进制体)。"""
if len(data) < 8 or data[:4] != MAGIC:
raise ValueError("bad frame magic")
n = _LEN.unpack_from(data, 4)[0]
if len(data) < 8 + n:
raise ValueError("truncated header")
header = json.loads(data[8:8 + n].decode("utf-8"))
return header, data[8 + n:]
def session_id(header):
return (header.get("session") or {}).get("id")
def check_session(header, session):
"""应答必须属于当前会话,防止串台。"""
got = session_id(header)
if got != session["id"]:
raise RuntimeError("session mismatch: got %r, want %r" % (got, session["id"]))