WebSocketでバイナリを送受信してみた(2)
クライアントからバイナリを送る確認ができたので、
バイナリに更にデータ乗っけて送ったりもらったりしてみる。
クライアント側
input:fileでファイルを参照したら、先頭にhelloworld文字列を追加した
バイナリデータとして送信する。
サーバ側からメッセージを受け取って、バイナリデータだったら
先頭の文字列と画像データに分けてそれぞれ表示する。
// BlobBuilder BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; // URL URL = window.URL || window.webkitURL; // document var doc = document; // WebSocketを開く var socket = new WebSocket('ws://' + location.host); // バイナリデータはArrayBufferで取得する socket.binaryType = 'arraybuffer'; // messageイベント socket.addEventListener('message', function(evt) { var data = evt.data; if (data.constructor === String) { // Stringの場合、pタグで追加 var p = doc.createElement('p'); p.textContent = data; doc.getElementById('messages').appendChild(p); } else if (data.constructor === ArrayBuffer) { // ArrayBufferの場合、付加された文字列と画像データに分ける // 先頭から10バイトを8ビット符号なし整数値の配列に var arr = new Uint8Array(data.slice(0, 10)); var key = []; for (var i = 0; i < 10; i++) { // キャラクタコードで文字列に変換して格納 key.push(String.fromCharCode(arr[i])); } // 付加した文字列をpタグで追加 var p = doc.createElement('p'); p.textContent = key.join(''); doc.getElementById('messages').appendChild(p); // 画像データ分をimgタグで追加 var builder = new BlobBuilder(); var img = new Image(); builder.append(data.slice(10)); img.src = URL.createObjectURL(builder.getBlob()); doc.getElementById('images').appendChild(img); } else { alert('nanigashi'); } }, false); // 文字列データをサーバに送信 doc.getElementById('sendText') .addEventListener('click', function(evt) { socket.send('test'); }, false); // fileを参照したらサーバに送信 doc.getElementById('image') .addEventListener('change', function(evt) { var file = evt.target.files[0]; var builder = new BlobBuilder(); builder.append('helloworld'); builder.append(file); // socket.send(file); socket.send(builder.getBlob()); }, false);
サーバ側
クライアントからバイナリデータを受け取ったら文字列と画像データに分解して、
文字列を返したあとに新たな文字列を先頭にくっつけた画像データを送信する。
// http server var connect = require('connect'); var httpServer = connect() .use(connect.static(__dirname + '/webroot')) .listen(1234); // WebSocket Server var WebSocketServer = require('websocket').server; var wsServer = new WebSocketServer({ httpServer : httpServer, autoAcceptConnections : true }); // クライアント接続イベント wsServer.on('connect', function(client) { // クライアントからのメッセージ受信イベント client.on('message', function(message) { if (message.type === 'utf8') { // 文字列だったら文字列としてそのまま送信 client.sendUTF(message.utf8Data); } else if (message.type === 'binary') { // バイナリだったら付加されている文字列を取り出し var src = message.binaryData; var text = new Buffer(10); src.copy(text, 0, 0, 10); // 受け取った文字列を返す client.sendUTF('receive:' + text.toString('utf8')); // 新たな文字列を付加して書き換えたバイナリデータとして送信 var str = 'helloagain'; var key = new Buffer(str); var buf = new Buffer(src.length); key.copy(buf, 0); src.copy(buf, 10, 10); client.sendBytes(buf); } else { console.log('nanigashi'); } }); });
結果
ArrayBufferを使っていろいろやることで、バイナリデータを分割したりして
いろいろできた。ちょうどFirefoxも12からArrayBufferのsliceができるようになってた。