Async::WebSocket gemの素振り その3 - @ledsun blog にて、ブロック呼び出しが入れ子になっていたのを解消しました。
次にAsync::WebSocket::Adapters::HTTP.openを展開します。
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.websocket?(request) Array(request.protocol).any? { |e| e.casecmp?(::Protocol::WebSocket::Headers::PROTOCOL) } end def self.open(request) if websocket?(request) response = ::Async::WebSocket::Response.for(request, protocol: nil) do |stream| framer = ::Protocol::WebSocket::Framer.new(stream) connection = ::Async::WebSocket::Connection.call(framer, nil, ::Protocol::WebSocket::Extensions::Server.default) yield connection ensure connection&.close stream.close end # Once we get to this point, we no longer need to hold on to the request: request = nil return response end end def self.call(env) req = ::Protocol::Rack::Request[env] res = open(req) do |conn| # Echo back! while message = conn.read conn.write message end end Protocol::Rack::Adapter.make_response(env, res) end end run App
また、ブロック呼び出しの入れ子が増えてしまいました。