workerman 5.2.3 默认支持向 websocket 或 tcp 客户端发送二进制数据,关键在于不经过字符串编码转换、直接写入原始字节流,并确保客户端能正确识别和解析。

Workerman 5.2.3 默认支持向 WebSocket 或 TCP 客户端发送二进制数据,关键在于**不经过字符串编码转换、直接写入原始字节流**,并确保客户端能正确识别和解析。它本身不强制要求数据为 UTF-8 字符串,只要底层连接协议允许(如 WebSocket 的二进制帧、TCP 原始字节),就能原样推送。
确认连接类型支持二进制
WebSocket 协议原生支持二进制帧(BINARY),Workerman 的 WebSocketConnection 对象默认可发;TCP 连接则天然支持任意字节。但需注意:
- 如果是 WebSocket,客户端(如浏览器
WebSocket对象)必须设置binaryType = 'arraybuffer'或'blob'才能接收二进制 - HTTP 连接不适用——HTTP 协议本身无二进制消息概念,仅适合文本响应
- 若用了自定义协议(如私有 TCP 协议),需确保
encode()方法返回的是string类型的原始字节,而非 JSON 编码后的字符串
直接发送 raw 字节(最常用方式)
对已建立的连接对象(如 $connection),调用 send() 并传入 PHP 字符串(string 类型,内部为 byte 序列)即可:
炫酷的jQuery二进制数字时钟,它的时分秒都是用二进制来表示,绿色表示该位值是1,灰色则表示0,原理是将时钟的时分秒分别实时转换成二进制,然后随着本地时间的更新而实时刷新
- 用
pack()构造结构化二进制数据(如头+长度+内容) - 用
file_get_contents()读取图片、音频等文件原始内容 - 用
hex2bin()或base64_decode()还原为原始字节
示例(发送一个 4 字节整数 + 一段 JPEG 数据):
```php$int32 = pack('N', 12345); // 网络字节序 uint32
$jpegData = file_get_contents('/path/to/image.jpg');
$binaryPayload = $int32 . $jpegData;
$connection->send($binaryPayload);
```
WebSocket 场景下显式声明二进制帧(可选但推荐)
虽然 Workerman 5.2.3 在检测到非 UTF-8 字符串时会自动使用二进制帧,但为明确语义、避免潜在编码误判,可手动触发:
- 调用
$connection->send($data, true)—— 第二个参数设为true表示强制以二进制帧发送(仅对 WebSocket 连接有效) - 该行为在源码中对应
WebSocketConnection::send()的$binary标志位,会跳过 UTF-8 检查,直接构造0x02类型帧
示例:
```php$pngBytes = file_get_contents('chart.png');
// 强制走 WebSocket 二进制帧
$connection->send($pngBytes, true);
```
避免常见陷阱
-
别用
json_encode()包裹二进制数据:JSON 不支持 raw bytes,会导致乱码或截断 -
别对二进制数据调用
utf8_encode()或mb_convert_encoding():会破坏原始字节 -
TCP 自定义协议需配好
input():确保input()能正确返回完整包长(比如按包头4字节读取后续长度),否则 Workerman 会缓存不完整数据,导致decode()拿不到整包 -
多进程环境下注意连接归属:二进制推送必须在持有该
$connection的 Worker 进程内执行;跨进程推送需通过Channel或 Redis 中转指令,再由目标进程操作真实连接










