1

サーバープッシュシステムの良い例かもしれません。システムには多くのユーザーがいて、ユーザー同士で会話することができます。次のように実行できます。1 人のユーザーが (websocket を介して) サーバーにメッセージを送信し、サーバーがそのメッセージを他のユーザーに転送します。重要なのは、ws (websocket オブジェクト) とユーザーの間のバインディングを見つけることです。以下のようなコード例:

EM.run {
  EM::WebSocket.run(:host => "0.0.0.0", :port => 8080, :debug => false) do |ws|
    ws.onopen { |handshake|
      # extract the user id from handshake and store the binding between user and ws
    }
    ws.onmessage { |msg|
      # extract the text and receiver id from msg
      # extract the ws_receiver from the binding
      ws_receiver.send(text)
    }
  end
}

次の問題を把握したい:

  1. wsディスクまたはデータベースに格納できるように、オブジェクトをシリアル化できますか? そうしないと、バインディングをメモリに保存することしかできません。

  2. em-websocket と websocket-rails の違いは何ですか?

  3. websocket におすすめの gem はどれですか?

4

2 に答える 2

1

以下は、em-websocketwebsocket-rails (長い間維持されていなかった)、 faye -websocket-railsおよびActionCableへの参照を含むChase Gilliam の簡潔な回答に追加されます。

Pleziフレームワークをお勧めします。これは、独立したアプリケーション フレームワークとしても、Rails Websocket 拡張機能としても機能します。

また、次の点についても検討します。

  1. 接続間でメッセージを保持する必要がありますか (つまり、他のユーザーがオフラインの場合、メッセージは「メッセージ ボックス」で待機する必要がありますか?メッセージはどのくらい待機する必要がありますか?)...?

  2. メッセージ履歴を保持しますか?

これらのポイントは、メッセージに永続的なストレージ (データベースなど) を使用するかどうかを決定するのに役立ちます。

つまり、Rails でPleziinit_plezi.rbを使用するには、アプリケーションのconfig/initializersフォルダに を作成します。(例として) 次のコードを使用します。

class ChatDemo
    # use JSON events instead of raw websockets
    @auto_dispatch = true
    protected #protected functions are hidden from regular Http requests
    def auth msg
        @user = User.auth_token(msg['token'])
        return close unless @user
        # creates a websocket "mailbox" that will remain open for 9 hours.
        register_as @user.id, lifetime: 60*60*9, max_connections: 5
    end
    def chat msg, received = false
        unless @user # require authentication first
           close
           return false
        end
        if received
           # this is only true when we sent the message
           # using the `broadcast` or `notify` methods
           write msg # writes to the client websocket
        end
        msg['from'] = @user.id
        msg['time'] = Plezi.time # an existing time object
        unless msg['to'] && registered?(msg['to'])
           # send an error message event
           return {event: :err, data: 'No recipient or recipient invalid'}.to_json
        end
        # everything was good, let's send the message and inform
        # this will invoke the `chat` event on the other websocket
        # notice the `true` is setting the `received` flag.
        notify msg['to'], :chat, msg, true
        # returning a String will send it to the client
        # when using the auto-dispatch feature
        {event: 'message_sent', msg: msg}.to_json
    end
end
# remember our route for websocket connections.
route '/ws_chat', ChatDemo
# a route to the Javascript client (optional)
route '/ws/client.js', :client

Plezi は独自のサーバー (Iodine、Ruby サーバー) をセットアップするため、アプリケーションからやその他のカスタム サーバーへpumaの参照を削除することを忘れないでください。thin

クライアント側では、Plezi が提供する Javascript ヘルパーを使用したい場合があります (オプションです)... 追加:

<script src='/es/client.js' />
<script>

    TOKEN = <%= @user.token %>;
    c = new PleziClient(PleziClient.origin + "/ws_chat") // the client helper
    c.log_events = true // debug
    c.chat = function(event) {
       // do what you need to print a received message to the screen
       // `event` is the JSON data. i.e.: event.event == 'chat'           
    }
    c.error = function(event) {
       // do what you need to print a received message to the screen
       alert(event.data);
    }
    c.message_sent = function(event) {
       // invoked after the message was sent
    }
    // authenticate once connection is established
    c.onopen = function(event) {
       c.emit({event: 'auth', token: TOKEN});
    }
    //  //  to send a chat message:
    //  c.emit{event: 'chat', to: 8, data: "my chat message"}
</script>

実際のメッセージ コードはテストしませんでした。これは単なるスケルトンであり、Userモデルを含む Rails アプリとtoken、質問に答えるためだけに編集したくない (違反ではありません) 必要があるためです。

于 2015-12-29T17:36:02.163 に答える
1

Websocket が非常に適しているユース ケースに近づいているので、正しい方向に進んでいます。

  1. Marshal を使用してオブジェクトをシリアル化することもできwsますが、websocket オブジェクトは、ある種の通信の抽象化であるという点で、http 要求オブジェクトに少し似ていると考えてください。おそらく、データをマーシャリング/保存するのが最善です。
  2. em-websocketは、Web マシン上に多かれ少なかれ直接構築された、より低い (っぽい) レバーの Websocket ライブラリです。websocket-railsは、Websocket のより高いレベルの抽象化であり、多くの優れたツールが組み込まれており、かなり適切なドキュメントが用意されています。これは、Web マシン上に構築されたfaye-websocket-rails の上に構築されています。* 注意: Rails 5 用の新しい websocket ライブラリである action cable は faye 上に構築されています。
  3. 私は過去に websocket-rails を使用しており、かなり気に入っています。それはあなたのために多くの世話をします。ただし、Rails 5 と Action Cable を使用できる場合は、それを実行してください。
于 2015-12-29T06:33:58.277 に答える