发送超64kB WebSocket消息时Ratchet服务抛出Underflow异常如何解决
异常触发原因
- WebSocket协议默认单帧最大载荷为64KB,当你发送的JSON消息(尤其是包含base64格式的图片文件)超过这个阈值时,浏览器端的JavaScript WebSocket实现会自动将消息拆分为多个分片帧依次发送
- Ratchet库的
WsServer默认未调整最大帧大小限制,也不会自动合并分片帧,收到不完整的分片帧时直接尝试解析校验,就会抛出UnderflowException异常,错误提示就是你看到的Frame must be coalesced before applying mask
解决方案
方案1:调整Ratchet最大帧限制(适配中小体积消息,改造成本最低)
直接在初始化WsServer时调用setMaxFrameSize方法,将最大帧阈值调整到符合业务需求的大小,比如设置为10MB,修改后的PHP服务端代码如下:
use Ratchet\Server\IoServer; use Ratchet\Http\HttpServer; use Ratchet\WebSocket\WsServer; use MyApp\Socket; $wsServer = new WsServer(new Socket()); // 按需调整最大帧大小,示例为10MB,单位是字节 $wsServer->setMaxFrameSize(10 * 1024 * 1024); $server = IoServer::factory( new HttpServer($wsServer), 8080 ); $server->run();
方案2:客户端分片传输(适配超大文件/消息,稳定性更高)
客户端将大消息拆分为多个小于64KB的分片,每个分片携带序号、总分片数等标识,服务端收到所有分片后再合并为完整的JSON字符串解析,不需要修改服务端默认配置,也能避免单条消息过大导致的连接超时问题。
方案3:服务端手动处理分片逻辑
如果需要兼容任意大小的消息,可以在服务端的Socket处理类中实现分片缓存逻辑,识别分片帧后先存入缓存,直到收到最后一个分片帧再合并成完整消息做后续处理。
内容的提问来源于stack exchange,提问作者Kok Meng
相关产品推荐
相关产品推荐

