2017-04-11 7 views
0

現在、私はWebSocketを使用してサーバーに画像を送信し、処理した後、返信します。具体的には、Sinatraとsinatra-websocketでRubyを使用しています。WebSocketを使用してクライアントとサーバー間の通信を高速化するにはどうすればよいですか?

私の開発サーバーでは、イメージをサーバーに送信し、処理せずに正確なイメージを取得するまでに2秒かかります。

AWS-EC2インスタンスでは、これには約15秒かかります。送信している画像ファイルは〜500kbです。私のアップロードとダウンロードのスピードはそれをはるかに上回ります。

どのようにこのプロセスをスピードアップできますか?これは画像を前後に送信する素朴な方法ですか?

編集:問題を複製するには、repoをAWS-EC2フリー層インスタンスでクローンして実行することができます。

+0

どのサーバーを使用しているのかわかりません...開発サーバーとEC2インスタンスの違いは何ですか? ...ルーティングスタック(アプリサーバーの前)は何ですか? ...また、私はネイティブのC Websocketサーバー(例えば、「iodine」宝石)でRubyを使用しても、アプリケーションロジックや処理量に関連した減速を経験するでしょうルーティング、同時負荷などが必要です。 – Myst

+0

私の開発サーバーはローカルです。したがって、ネットワークの待ち時間が存在しないため、速度は驚くべきことではありません。 私のアプリケーションのロジックが分かれば、このような分離されたケースは単純に次のようになります。 クライアント - > 400kbを64base符号化したimgをサーバーに送信 - >シン・サーバーがイメージを受信 - >サーバーは、 – Mark

答えて

0

これは、質問が問題を絞り込むのに十分な詳細情報を提供していないため、回答よりも多くの、またはテストヘルパーです。


Pleziを使用して簡単なテストアプリケーションを作成しました。私はプレッツィの作家であるため、あなたのスタックを学ぶよりも私にとっては簡単でした。

私のコンピュータでは、79Mバイト〜3Mバイトのファイルで完全に動作します。

Herokuのに〜3Mbの往復は3秒私のシステムを取って、TCP/IPのウォームアップが完了した後にダウン〜2.5秒に行きました...

...しかし、私のインターネットの速度は、おそらく(テストを行ういます私のレセプションは現時点では低いので、遅くなる可能性があります)。

問題を再現できるかどうかは不明ですが、この回答のコードを使用してサーバーをテストできます。

ラウンドトリップに10秒以上かかる場合は、EC2スタックかもしれません。私は〜500Kbのために10秒が合理的とは思わない。

一方、往復時間が短い場合は、アプリケーションまたはRubyスタックをテストした方法かもしれません。その場合は解決策がplezi(またはiodine native websocket design)に切り替えることが考えられます。

あなたは(あなたもplezi宝石、おそらくGemfile.lockと宝石のファイルが必要になります覚えておいてください)config.ruに次のコードを貼り付けることができます:

# The roundtrip html client 
ROUNDTRIP_CLIENT = <<CLIENT_EFO 
<html> 
    <head> 
    <script src = '/client.js'></script> 
    </head> 
    <body> 
    <input type='file' id='test_f' lable='file to upload'></input> 
    <button id='test_b'>run test</button> 
    <div id='output'></div> 
    <script> 
    var client; 
    window.onload = function (e) { 
    client = new PleziClient(); 
    client.autoreconnect = true; 
    client.roundtrip = (e) => { 
     var d = new Date(); 
     e.completed_at = d.getTime(); 
     console.log(e); 
     document.getElementById('output').innerHTML += "<p>Test for " + 
     "<a href='" + e.data + "' target='_blank'>" + Math.round(e.data.length/1024)+ "Kb encoded file</a>" + 
     " completed in " + (e.completed_at - e.time) + "ms</p>"; 
    } 
    client.onopen = (e) => console.log("Websocket client open", e); 
    } 

    function run_test(e) { 
    console.log("File submitted."); 
    reader = new FileReader(); 
    reader.onloadend = function(e) 
    { 
     console.log("File loaded, " + e.target.result.length + "bytes... starting test.") 
     var d = new Date(); 
     client.emit({event: "roundtrip", data: e.target.result, time: d.getTime() }); 
    } 
    reader.readAsDataURL(document.getElementById('test_f').files[0]); 
    return false; 
    } 
    document.getElementById('test_b').onclick = run_test; 
    </script> 
    </body> 
</html> 
CLIENT_EFO 

# require plezi 
require 'plezi' 
# For security, Iodine limists websocket messages. 
# We update the default limit from ~250Kb to ~4Mb. 
# This replaces the commandline option: iodine -v -maxms 4194304 
Iodine::Rack.max_msg_size = 4194304 

# the roundtrip controller... quite simple. 
class RoundTrip 
    # return the roundtrip client. 
    def index 
    ROUNDTRIP_CLIENT 
    end 
    # echo back the websocket message - we're just testing the round trip. 
    def on_message data 
    write data 
    end 
end 
# Set the plezi root route to the RoundTrip controller 
Plezi.route '/', RoundTrip 
# Set the client javascript route - I'm using it as a heler. 
Plezi.route '/client.js', :client 
# Set Rack to run the Plezi application 
run Plezi.app 

端末からコードを実行するには、iodineを使用コマンド(それはPleziが必要ですiodineサーバーを起動します。


EDIT

(コメント内の)git-repoへのリンクから、私はJSONがサーバーによって解析されてから再発行されることに気付きました。

これをエミュレートするために、サンプルコードを更新しました。

これは、JSONの解析と再フォーマットがメモリの割り当てとCPU時間を必要とするデータのコピーを作成するので、レポのコードが行うように見えるはずです。 。

コードの唯一の変更はRoundTripコントローラクラスにありますが、コピー+貼り付けの利便性のためにすべてを貼り付けています。

置き、あなたのapp.rbファイルに次のコードは、(plezi宝石をインストールするinstall.shを編集することを忘れないでください):

# The roundtrip html client 
ROUNDTRIP_CLIENT = <<CLIENT_EFO 
<html> 
    <head> 
    <script src = '/client.js'></script> 
    </head> 
    <body> 
    <input type='file' id='test_f' lable='file to upload'></input> 
    <button id='test_b'>run test</button> 
    <div id='output'></div> 
    <script> 
    var client; 
    window.onload = function (e) { 
    client = new PleziClient(); 
    client.autoreconnect = true; 
    client.roundtrip = (e) => { 
     var d = new Date(); 
     e.completed_at = d.getTime(); 
     console.log(e); 
     document.getElementById('output').innerHTML += "<p>Test for " + 
     "<a href='" + e.data + "' target='_blank'>" + Math.round(e.data.length/1024)+ "Kb encoded file</a>" + 
     " completed in " + (e.completed_at - e.time) + "ms</p>"; 
    } 
    client.onopen = (e) => console.log("Websocket client open", e); 
    } 

    function run_test(e) { 
    console.log("File submitted."); 
    reader = new FileReader(); 
    reader.onloadend = function(e) 
    { 
     console.log("File loaded, " + e.target.result.length + "bytes... starting test.") 
     var d = new Date(); 
     client.emit({event: "roundtrip", data: e.target.result, time: d.getTime() }); 
    } 
    reader.readAsDataURL(document.getElementById('test_f').files[0]); 
    return false; 
    } 
    document.getElementById('test_b').onclick = run_test; 
    </script> 
    </body> 
</html> 
CLIENT_EFO 

# require plezi 
require 'plezi' 
# For security, Iodine limists websocket messages. 
# We update the default limit from ~250Kb to ~4Mb. 
# This replaces the commandline option: iodine -v -maxms 4194304 
Iodine::Rack.max_msg_size = 4194304 

# the roundtirp controller... quite simple. 
class RoundTrip 
    @auto_dispatch = true 
    # return the roundtrip client. 
    def index 
    ROUNDTRIP_CLIENT 
    end 
    # Using Auto-Dispatch, the JSON is parsed and this event is invoked. 
    def roundtrip msg 
    # Hash results are automatically converted into JSON and emitted 
    msg 
    end 
end 
# Set the plezi root route to the RoundTrip controller 
Plezi.route '/', RoundTrip 
# Set the client javascript route - I'm using it as a heler. 
Plezi.route '/client.js', :client 
# Plezi will start automatically when the script exits 

は、あなたのレポでの場合と同様に同じruby app.rbコマンドを使用し、端末からのコードを実行するには既存のアプリ。

古い単に提供するコードと「エコー」レスポンス、新しいコード(ほぼ同じに見えます)、さらにいくつかのステップがありますが:

自動ディスパッチを使用して
  • 、Pleziフレームワークが自動的に解析し、 JSONを呼び出し、コントローラーのメソッド(roundtrip)のイベント(「ラウンドトリップ」)をルーティングします。

  • このメソッドは、解析されたデータでHashを受け取り、そのハッシュをPleziに返します。

  • フレームワークでは、このリポジトリの動作と同様である...、ハッシュを収集JSONオブジェクトをフォーマットし、その結果をバック放出する(非文字列やハッシュ結果は無視される)...

+0

ちょっとミスト、私は間違いなくPleziをチェックし、あなたのコードをテストします。私の問題を複製することに興味があれば、AWS-EC2(フリーティア)を作成し、私の[repo](https://github.com/markediez/ecs193ab)を複製することができます。 – Mark

+0

@マーク、私は、レポのコードがJSONオブジェクトを解析してフォーマットすることに気付きました。私はJSON解析をフローの一部として提供するために私の答えを編集しました。私のマシンでは20msほど遅くなります。 – Myst

関連する問題