@ledsun blog

無味の味は佳境に入らざればすなわち知れず

Async::WebSocket gemの素振り その2

Async::WebSocket gemの使い方がどうにもイメージできません。 Async::WebSocket gemの素振り - @ledsun blog より、もう少しプリミティブな使い方をしてみます。

準備

bundle init
bundle add falcon async-websocket

サーバー

require 'async/websocket/adapters/http'
require "protocol/rack/request"
require "protocol/rack/adapter"

def open(env, &block)
  request = ::Protocol::Rack::Request[env]

  if response = Async::WebSocket::Adapters::HTTP.open(request, &block)
    return Protocol::Rack::Adapter.make_response(env, response)
  end
end

app = lambda do |env|
  open(env) do |connection|
    # Echo back!
    while message = connection.read
       connection.write message
     end
  end or [404, {}, []]
end

run app

Async::WebSocket::Adapters::Rack より一段低い Async::WebSocket::Adapters::HTTP を見つけたので使ってみます。

クライアント

#!/usr/bin/env ruby
# frozen_string_literal: true

require "async"
require "async/http"
require "async/websocket"

URL = "ws://localhost:8000/"

Async do |task|
  endpoint = Async::HTTP::Endpoint.parse URL,
                                         alpn_protocols: Async::HTTP::Protocol::HTTP11.names

  connection = Async::WebSocket::Client.connect(endpoint)
  message = Protocol::WebSocket::TextMessage.generate("Hello World!")
  connection.write message
  connection.flush

  recive_message = connection.read
  puts message.parse

  connection.close
end

実行

bundle exec falcon serve --bind "http://localhost:8000"
./client.rb
Hello World!

もしかすると、僕が使いたいのは GitHub - socketry/protocol-websocket: Provides a low-level implementation of the WebSocket protocol according to RFC6455. なのかもしれません。