一些理論知識
先說一下deflate演算法吧,deflate是zip壓縮檔案的預設演算法, 其實deflate現在不光用在zip檔案中, 在7z, xz等其他的壓縮檔案中都用, 實際上deflate只是一種壓縮資料流的演算法,任何需要流式壓縮的地方都可以用。
也就是說 zlib 格式, gzip 格式,是檔案格式,deflate 是這些檔案格式使用的壓縮演算法。
傳輸方式
deflate 壓縮後是二進位制,通常有兩種傳輸方式:
- 二進位制
- Base64編碼
二進位制
PHP
// 壓縮,注意:其中 ZLIB_ENCODING_DEFLATE 引數是不能少的
$data = gzdeflate(json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), 6, ZLIB_ENCODING_DEFLATE);
// 使用 swoole 以二進位制的方式傳送
$webSocket->push($fd, $data, WEBSOCKET_OPCODE_BINARY);
JavaScript
// 訊息事件
ws.onmessage = function(e) {
// 轉換前
console.log(e.data);
// 開始轉換
var blob = e.data;
var reader = new FileReader();
reader.readAsBinaryString(blob);
reader.onload = function (evt) {
var data = pako.inflate(evt.target.result, { to: `string` })
// 轉換後
console.log(JSON.parse(data))
};
};
Base64編碼
通常在 WebSoctet 不會使用這種方法,但是在介面或其他文字傳輸中會使用到。
PHP + JavaScript
<script type=`text/javascript`>
const compressedDEFLATE = `<?php echo base64_encode(gzdeflate(`Compress me`, 6, ZLIB_ENCODING_DEFLATE )); ?>`;
function atos(arr) {
for (var i=0, l=arr.length, s=``, c; c = arr[i++];)
s += String.fromCharCode(
c > 0xdf && c < 0xf0 && i < l-1
? (c & 0xf) << 12 | (arr[i++] & 0x3f) << 6 | arr[i++] & 0x3f
: c > 0x7f && i < l
? (c & 0x1f) << 6 | arr[i++] & 0x3f
: c
);
return s
}
console.log(atos(pako.ungzip(atob(compressedDEFLATE))));
</script>
Swoole WebSoctet 框架
安利一個基於 Swoole 的 WebSoctet 開發框架: MixPHP