Async::WebSocket gemの素振り その4 - @ledsun blog でブロック呼び出しの入れ子が増えてしまったので、再度展開します。 理解しやすくするため、エラー処理も消します。
require 'async/websocket/response' require 'async/websocket/connection' require 'protocol/websocket/framer' require 'protocol/websocket/extensions' require "protocol/rack/request" require "protocol/rack/adapter" class App def self.call(env) req = ::Protocol::Rack::Request[env] res = ::Async::WebSocket::Response.for(req, protocol: nil) do |stream| framer = ::Protocol::WebSocket::Framer.new(stream) conn = ::Async::WebSocket::Connection.call framer, nil, ::Protocol::WebSocket::Extensions::Server.default # Echo back! while message = conn.read conn.write message end res end Protocol::Rack::Adapter.make_response(env, res) end end run App
コネクションを開く処理と、メッセージを受け取る処理が一箇所にある点に違和感があります。 一見すると、WebSocket経由のメッセージを全部受け取ってから、コネクション確立のレスポンスを返しそう見えます。
実際に動かすと、レスポンスは即座に返してコネクション確立して、メッセージを待ちます。
::Async::WebSocket::Response.for
の辺りに秘密がありそうです。
次はそこを見ていきます。