msgpack.js RC

MessagePack 発案者様から「末席あいてますよ」とお言葉をいただいたので、uupaa.js に一切依存せず、ソースコード単体で利用可能なスピンオフ版を作成しました。

  • Many bugfix(especially - IEEE754)
  • Test case was enhanced
  • Download and Upload functions
    • msgpack.download(url, option, callback) -> download binary data by GET method.
    • msgpack.upload(url, option, callback) -> upload base64 data by PUT method.
  • Pack and Unpack functions
    • msgpack.pack(Mix) is converted into ByteArray of the MessagePack format.
      • Mix are undefined, null, Object, Array, String and Number types.
      • ByteArray is [0x00, 0xff, ...] alias.
    • msgpack.unpack(ByteArray):Mix is restored.
  • Support WebWorkers
    • msgpack.download(url, { worker: true }, callback)
    • msgpack.upload(url, { worker: true }, callback)
    • msgpack.worker - String(= "msgpack.js"): WebWorkers script URL
  • Support Browsers
    • A Grade: Google Chrome 4+, Safari5+, Firefox3.6+, Opera10.50+, iPhone 3G+, IE8+
    • B Grade: Safari3.1+, Firefox3+, Opera9.6+, IE6+

Benchmark (JSON vs msgpack)

(unit: ms)

Biggest data (over 100000 objects)
JSON.stringify + JSON.parse msgpack.pack + msgpack.unpack rario
Chrome 6(dev) 3818 2240 170%
Safari 5 761 3564 21%
Opera 10.60(alpha) 561 2178 25%
Bigger data (over 10000 objects)
JSON.stringify + JSON.parse msgpack.pack + msgpack.unpack rario
Chrome 6(dev) 214 195 110%
Safari 5 72 337 21%
Firefox 3.6 89 654 13%
Firefox 3.0 656 698 94%
Opera 10.60(alpha) 64 203 31%
IE 8 156 2094 7%
IE 6 12203 27297 44%
iPhone 3GS 319 2763 11%
Big data (over 1000 objects)
JSON.stringify + JSON.parse msgpack.pack + msgpack.unpack rario
Chrome 6(dev) 20 21 95%
Safari 5 5 28 17%
Firefox 3.6 7 63 11%
Firefox 3.0 58 61 95%
Opera 10.60(alpha) 5 18 27%
IE 8 15 141 10%
IE 6 281 516 54%
iPhone 3GS 33 285 11%

How to use

// msgpack.pack(), msgpack.unpack()

<script src="msgpack.js"></script>
<script>
var byteArray = msgpack.pack({ hello: "world" });

alert( msgpack.unpack(byteArray).hello ); // world
</script>

// msgpack.download() with WebWorkers

<script src="msgpack.js"></script>
<script>
function callback(response) {
    if (response.ok) {
        alert( response.length ); // binary-data.length
        alert( response.data );  // Mix (JavaScript Object)
    } else {
        alert( "ERROR STATUS = " + response.status ); // xhr.status
    }
}

// msgpack.worker = "http://example.com/js/msgpack.js";

msgpack.download(url, { worker: true }, callback);
</script>

// msgpack.upload() with WebWorkers

<script src="msgpack.js"></script>
<script>
function callback(response) {
    if (response.ok) {
        alert( response.length ); // upload-data.length (base64.length)
        alert( response.data ); // xhr.responseText (optional)
    } else {
        alert( "ERROR STATUS = " + response.status ); // xhr.status
    }
}

// msgpack.worker = "http://example.com/js/msgpack.js";

var mix = { hello: "world" };

msgpack.upload("http://example.com/upload.php", { worker: true, data: mix, timeout: 5 }, callback);
</script>

// upload.php

<?php
// see http://php.net/manual/en/features.file-upload.put-method.php
$data = fopen("php://input", "r");
$fp = fopen("msgpack.bin", "w");        // output filename

while ($part = fread($data, 8192)) {    // 8192 bytes
    fwrite($fp, base64_decode($part));  // base64 decode
}

fclose($fp);
fclose($data);

print_r(getallheaders());
 ?>

えーと

upload.php は見たとおりサイバーノーガード状態なので、一斉にアップロードしたりするとアレです。このページの先頭部分で紹介している msgpack download / upload demo で[1MB x 3]などのテストが動かない場合は zip ファイルを適当な場所に設置して動かしてみてください。

上記の upload.php の中ではわざわざファイルに書き込んでいますが、ストリームのまま処理することもできます。PHP以外の言語でも、それほど難しい処理は必要ないでしょう。

また、MessagePack とは関係ありませんが、Google Chrome5+ からは WebWorkers の中で WebSockets が使えるため、将来はコネクションを張ったまま双方向でデータの流し込みが可能になります。