class ACIrb::EventChannel

Event channel interface

Attributes

rest[RW]

Public Class Methods

new(rest, _options = {}) click to toggle source
# File lib/acirb/events.rb, line 21
def initialize(rest, _options = {})
  @rest = rest

  uri = URI.parse(@rest.baseurl)

  if uri.scheme == 'https'
    scheme = 'wss'
    secure = true
  else
    scheme = 'ws'
    secure = false
  end

  url = '%s://%s/socket%s' % [scheme, uri.host, rest.auth_cookie]

  @handshake = WebSocket::Handshake::Client.new(url: url)
  @frame = WebSocket::Frame::Incoming::Server.new(version: @handshake.version)

  @socket = TCPSocket.new(@handshake.host, uri.port)

  if secure
    puts 'connecting over secure websocket'
    ctx = OpenSSL::SSL::SSLContext.new

    ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE unless rest.verify

    ssl_sock = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
    ssl_sock.sync_close = true
    ssl_sock.connect

    @transport_socket = @socket
    @socket = ssl_sock
  else
    @transport_socket = nil
  end

  @socket.write(@handshake.to_s)
  @socket.flush

  loop do
    data = @socket.getc
    next if data.nil?

    @handshake << data

    if @handshake.finished?
      fail @handshake.error.to_s unless @handshake.valid?
      @handshaked = true
      break
    end
  end
end

Public Instance Methods

close() click to toggle source
# File lib/acirb/events.rb, line 118
def close
  @socket.close
end
receive(timeout = nil) click to toggle source
# File lib/acirb/events.rb, line 86
def receive(timeout = nil)
  fail WebSocketNoHandshake unless @handshaked

  readable, writable, error = IO.select([@socket], nil, nil, timeout)
  if readable
    begin
      data = @socket.read_nonblock(1024)
    rescue Errno::EAGAIN, Errno::EWOULDBLOCK, (IO::WaitReadable if defined?(IO::WaitReadable)) => e
      puts '%s, retrying' % e
      retry
    end
  else
    fail ApicWebSocketRecvTimeout, 'Timeout for websocket read'
  end
  @frame << data

  messages = []
  while message = @frame.next
    if message.type === :ping
      send(message.data, :pong)
      return messages
    end
    messages << message.to_s
  end

  events = []
  messages.each do |msg|
    events += MoEvent.parse_event(self, msg.to_s)
  end
  events
end
send(data, type = :text) click to toggle source
# File lib/acirb/events.rb, line 74
def send(data, type = :text)
  fail WebSocketNoHandshake unless @handshaked

  data = WebSocket::Frame::Outgoing::Client.new(
    version: @handshake.version,
    data: data,
    type: type
  ).to_s
  @socket.write data
  @socket.flush
end