WebSocketでバイナリを送受信してみた
Firefox11になってとっくにWebSocketのベンダープレフィックスとれてたし、
バイナリデータの送受信の辺りがどうなってるか確認してみた。
確認したブラウザはFirefox11.0とGoogle Chrome18.0.1025.162。
サーバ側
node.jsで実装する。
httpサーバ用にconnectを使って、WebSocketサーバはWebSocket-Nodeを使う。
それぞれnpm install connect、npm install websocketでモジュール入れる。
サーバ側のコードは次の通り。
// 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') { // バイナリだったらバイナリとしてそのまま送信 client.sendBytes(message.binaryData); } else { console.log('nanigashi'); } }); });
クライアント側からメッセージ届いたら、タイプに応じてそのまま返すだけ。
クライアント側
ボタンを押したら固定文字列を送るのと、ファイル参照したらそれを送るようにする。
送ったデータがサーバから送り返されたら、タイプに応じてそれぞれのdivの中に書きだす。
HTML次のとおり。
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>WebSocket Test</title> </head> <body> <input id="sendText" type="button" value="文字列を送る" /> <input id="image" name="image" type="file" /> <!-- 文字列受信ログ --> <div id="messages"></div> <!-- 画像受信ログ --> <div id="images"></div> <script type="text/javascript" src="index.js"></script> </body> </html>
クライアント側のJavaScript。
// URL URL = window.URL || window.webkitURL; // document var doc = document; // WebSocketを開く var socket = new WebSocket('ws://' + location.host); // 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 === Blob) { // Blobの場合、imgタグで追加 var img = new Image(); img.src = URL.createObjectURL(data); 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]; socket.send(file); }, false);
結果
Firefox、Google Chrome共に送ったバイナリデータを送り返してもらって表示できた。