class Client

Synchronous websocket client Based on github.com/rails/rails/blob/v5.0.1/actioncable/test/client_test.rb

Constants

WAIT_WHEN_EXPECTING_EVENT
WAIT_WHEN_NOT_EXPECTING_EVENT

Public Class Methods

new(ignore: [], url: Anycablebility.config.target_url, cookies: "") click to toggle source

rubocop: disable Metrics/AbcSize rubocop: disable Metrics/MethodLength

# File lib/anycablebility/client.rb, line 14
def initialize(ignore: [], url: Anycablebility.config.target_url, cookies: "")
  ignore_message_types = @ignore_message_types = ignore
  messages = @messages = Queue.new
  closed = @closed = Concurrent::Event.new
  has_messages = @has_messages = Concurrent::Semaphore.new(0)

  open = Concurrent::Promise.new

  @ws = WebSocket::Client::Simple.connect(
    url,
    headers: {
      "COOKIE" => cookies
    }
  ) do |ws|
    ws.on(:error) do |event|
      event = RuntimeError.new(event.message) unless event.is_a?(Exception)

      if open.pending?
        open.fail(event)
      else
        messages << event
        has_messages.release
      end
    end

    ws.on(:open) do |_event|
      open.set(true)
    end

    ws.on(:message) do |event|
      if event.type == :close
        closed.set
      else
        message = JSON.parse(event.data)

        next if ignore_message_types.include?(message["type"])
        messages << message
        has_messages.release
      end
    end

    ws.on(:close) do |_event|
      closed.set
    end
  end

  open.wait!(WAIT_WHEN_EXPECTING_EVENT)
end

Public Instance Methods

close() click to toggle source
# File lib/anycablebility/client.rb, line 79
def close
  sleep WAIT_WHEN_NOT_EXPECTING_EVENT

  raise "#{@messages.size} messages unprocessed" unless @messages.empty?

  @ws.close
  wait_for_close
end
closed?() click to toggle source
# File lib/anycablebility/client.rb, line 92
def closed?
  @closed.set?
end
receive() click to toggle source

rubocop: enable Metrics/AbcSize rubocop: enable Metrics/MethodLength

# File lib/anycablebility/client.rb, line 65
def receive
  raise "Timed out to receive message" unless
    @has_messages.try_acquire(1, WAIT_WHEN_EXPECTING_EVENT)

  msg = @messages.pop(true)
  raise msg if msg.is_a?(Exception)

  msg
end
send(message) click to toggle source
# File lib/anycablebility/client.rb, line 75
def send(message)
  @ws.send(JSON.generate(message))
end
wait_for_close() click to toggle source
# File lib/anycablebility/client.rb, line 88
def wait_for_close
  @closed.wait(WAIT_WHEN_EXPECTING_EVENT)
end