RubyでWebSocketクライアントを書く その2 - @ledsun blog でWebSocketコネクションが確立できました。 今回はWebSocketを使ってサーバーとメッセージを送受信します。
#!/usr/bin/env ruby # frozen_string_literal: true require "erb" require "socket" require_relative "protocol_websocket_server/web_socket" URL = "ws://localhost:2345/" module WANDS class HTTPResponse attr_reader :header def parse(stream) @response_string = read(stream) parse_response_string(@response_string) end def to_s @response_string end private def read(stream) response_string = "" while (line = stream.gets) != "\r\n" response_string += line end response_string end def parse_response_string(response_string) headers, _body = response_string.split("\r\n\r\n", 2) headers_lines = headers.split("\r\n") _status_line = headers_lines.shift @header = headers_lines.map do |line| key, value = line.split(': ', 2) [key.downcase, [value]] end.to_h end end class UpgradeWebSocketRequest include ::Protocol::WebSocket::Headers TEMPLATE = <<~REQUEST GET / HTTP/1.1 Host: <%= @host %>:<%= @port %> Connection: Upgrade Upgrade: websocket Sec-WebSocket-Version: 13 Sec-WebSocket-Key: <%= @key %> REQUEST def initialize(host, port) @erb = ERB.new(TEMPLATE) @host = host @port = port @key = Nounce.generate_key end def to_s @erb.result(binding).gsub(/\r?\n/, "\r\n") end def verify(response) accept_digest = response.header[SEC_WEBSOCKET_ACCEPT].first accept_digest == Nounce.accept_digest(@key) || raise("Invalid accept digest") end end end request = WANDS::UpgradeWebSocketRequest.new('localhost', 2345) puts request.to_s socket = TCPSocket.new('localhost', 2345) socket.write(request.to_s) socket.flush puts 'Request sent' response = WANDS::HTTPResponse.new response.parse(socket) puts "Response: #{response.to_s}" request.verify response web_socket = WebSocket.new(socket) web_socket.write("Hello World!") puts web_socket.gets socket.close
RubyでつくるWebSocketサーバーにprotocol-websocket gemを取り入れる その6 - @ledsun blog で作成したWebSocket
クラスがそのままつかえました。
これでPure RubyなTCPSocketライクなインターフェースを持つWebSocket用のクラスが作成できそうです。