なっく日報

技術やら生活やらのメモ

WebSocketでファイルアップロードした方がいいこともあるんじゃないか

と、思い実験してみました。

※ 主に、WebSocket通信がメインの同期型のサービスを想定しています。アップロードの度にTCPコネクションを余計に張る必要がなくなるし、HTTP版の認証周りの作り込みが不要になるのでよいのではと思い。

実験内容

1GBくらいあるファイルをWebSocketのバイナリモードでサーバに送りつけます。 その間、

  • サーバ側からpush通信可能か?
  • サーバのメモリ使用量が大変なことになってないか?

等チェックします。

ソース

client側

'use strict';
var fs = require('fs');
var WebSocket = require('ws');

var ws = new WebSocket('ws://localhost:8080/', {
  protocolVersion: 8,
});

setInterval(function() {
  console.log(process.memoryUsage());
}, 3000);

ws.on('open', function open() {
  console.log('オーポン');

  fs.readFile('/Users/hoge/Downloads/FlashBuilder_4_6_LS10.dmg', function(err, data) {
    if (err) {
      throw err;
    }

    console.log('#############################################send start#########');

    ws.send(data, {
      binary: true,
    });
  });
});

ws.on('close', function close() {
  console.log('disconnected');
});

ws.on('message', function(data, flags) {
  console.log('message', data);
});

server側

'use strict';
var WebSocketServer = require('ws').Server;
var server = new WebSocketServer({ port: 8080 });

server.on('connection', function connection(ws) {
  setInterval(function() {
    console.log(process.memoryUsage());
    console.log('send');
    ws.send('something');
  }, 3000);

  ws.on('message', function(message) {
    console.log('received: %s', message);
  });
});

実行

npm i
node server.js
node client.js

結果

死んだ(完)

#
# Fatal error in ../deps/v8/src/handles.h, line 48
# CHECK(location_ != NULL) failed
#

==== C stack trace ===============================

 1: ??
 2: ??
 3: ??
 4: ??
 5: ??
 6: ??
 7: ??

所感

  • wsモジュールだとstreamが使えないので、重いファイルだとクライアント/サーバ側両方でメモリ食いそうです。そもそも筋が良くないかもしれません。
  • アップロード中にサーバ側からpushするのは問題ありませんでした。
  • https://github.com/Automattic/socket.io とか http://binaryjs.com/ とか使えばいけそうだけど、そこまで頑張る必要は今回はないすかね。。