class WsSyncClient

Synchronous socket.

Public Class Methods

new(url, options = {}) click to toggle source

Create a socket.

@param [String] url a ws:// URL @param [Hash] options socket creation options @option options [Socket] raw create this socket on top of a raw socket.

# File lib/ws_sync_client.rb, line 12
def initialize(url, options = {})
  @url = url
  @handshake = WebSocket::Handshake::Client.new url: @url

  if options[:raw]
    @socket = options[:raw]
  else
    @socket = self.class.raw_socket @handshake.host, @handshake.port
  end
  @max_recv = 4096

  handshake
  @closed = false
  @incoming = WebSocket::Frame::Incoming::Client.new(
      version: @handshake.version)
  if leftovers = @handshake.leftovers
    @incoming << leftovers
  end
end
raw_socket(host, port, timeout = 30) click to toggle source

Create a raw Socket connected to a host and port.

@param [String] host hostname (e.g., DNS, mDNS, “localhost” name) @param [Integer] port the port that the server listens to @param [Number] timeout number of seconds to wait for the connection to

succeed

@return [Socket] the raw socket

# File lib/ws_sync_client.rb, line 123
def self.raw_socket(host, port, timeout = 30)
  Addrinfo.foreach host, port, nil, :STREAM, nil,
                   Socket::AI_NUMERICSERV do |info|
    begin
      return info.connect
    rescue StandardError
      # Try the next address.
    end
  end
  nil
end

Public Instance Methods

close(code = 0, reason = '') click to toggle source

Closes the WebSocket.

@param [Integer] code @param [String] reason

# File lib/ws_sync_client.rb, line 72
def close(code = 0, reason = '')
  return if @closed
  frame = WebSocket::Frame::Outgoing::Client.new version: @handshake.version,
      data: '', type: :close
  @socket.send frame.to_s, 0
  @socket.close
  @closed = true
end
recv_frame() click to toggle source

Receive a WebSocket frame.

@return [String] the frame data

# File lib/ws_sync_client.rb, line 44
def recv_frame
  loop do
    frame = @incoming.next
    if frame.nil?
      recv_bytes
      next
    end

    case frame.type
    when :text
      return frame.data
    when :binary
      return frame.data
    when :ping
      send_pong frame.data
    when :pong
      # Ignore pong, since we don't ping.
    when :close
      @socket.close
      @closed = true
    end
  end
end
send_frame(data) click to toggle source

Send a WebSocket frame.

@param [String] data the data to be sent

# File lib/ws_sync_client.rb, line 35
def send_frame(data)
  frame = WebSocket::Frame::Outgoing::Client.new version: @handshake.version,
      data: data, type: :text
  @socket.send frame.to_s, 0
end

Private Instance Methods

handshake() click to toggle source

Complete the WebSocket handshake.

@private This is used in the constructor

# File lib/ws_sync_client.rb, line 85
def handshake
  @socket.send @handshake.to_s, 0

  until @handshake.finished?
    bytes = @socket.recv @max_recv
    @handshake << bytes
  end
  unless @handshake.valid?
    raise RuntimeError, 'Invalid WebSocket handshake'
  end
end
recv_bytes() click to toggle source

Receive a packet from the underlying raw socket.

@private This is used in {WsSync#recv_frame}.

# File lib/ws_sync_client.rb, line 102
def recv_bytes
  bytes = @socket.recv @max_recv
  @incoming << bytes
end
send_pong(ping_data) click to toggle source

Send

# File lib/ws_sync_client.rb, line 109
def send_pong(ping_data)
  frame = WebSocket::Frame::Outgoing::Client.new version: @handshake.version,
      data: ping_data, type: :pong
  @socket.send frame.to_s, 0
end