Swoole WebSoctet 使用 zlib 壓縮之 PHP 與 pako.js

一些理論知識

先說一下deflate算法吧,deflate是zip壓縮文件的默認算法, 其實deflate如今不光用在zip文件中, 在7z, xz等其餘的壓縮文件中都用, 實際上deflate只是一種壓縮數據流的算法,任何須要流式壓縮的地方均可以用。javascript

也就是說 zlib 格式, gzip 格式,是文件格式,deflate 是這些文件格式使用的壓縮算法。php

傳輸方式

deflate 壓縮後是二進制,一般有兩種傳輸方式:java

  • 二進制
  • Base64編碼

二進制

PHPgit

// 壓縮,注意:其中 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);

JavaScriptgithub

// 消息事件
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 不會使用這種方法,可是在接口或其餘文本傳輸中會使用到。web

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 開發框架: MixPHPjson

相關文章
相關標籤/搜索