Index
根据所有调试过程,整理完整的通信协议和时序:完整逻辑梳理如下:
连接阶段:前端主动 TCP 连接 38438 端口后,什么都不发,等服务端先开口。服务端必须立刻(不能有任何延迟)发送角色名 b'character_paimon',前端收到后才认为握手完成,开始录音准备。
每轮对话:前端按住录音键后,把 WAV 数据切成 1024 字节的包逐个发送,最后一包末尾追加 b'?!' 作为结束标志。服务端每收到一包就必须立刻回一个 b'sb' 作为 ACK(不能漏,前端依赖这个节奏控流)。服务端用累积 buffer 检测末尾的 b'?!' 来判断一个完整 WAV 是否接收完毕。
关键的 ≥2s 延迟:服务端收到完整 WAV 后,不能立刻回复。因为前端在收到 stream_finished 之后,需要一段时间重启 ReadMessageAsyncTask 接收线程,如果服务端回复太快,前端的读线程还没就绪,数据就丢失了,前端就会超时断开。这是整个调试过程中最核心的发现。
回复格式:WAV 二进制数据 + b'?!' + b'1'(情感值 1-3),然后 sleep 0.5s 后再发 b'stream_finished',前端收到 stream_finished 才认为本轮结束,重启读线程,准备下一轮。
断开:前端关闭连接时,服务端 recv() 返回空字节 b'',此时关闭 socket,回到 accept() 等待新连接。