class Bogo::Websocket::Client
Simple websocket client
Attributes
client[R]
@return [WebSocket::Frame::Incoming::Client]
connection[R]
@return [TCPSocket, OpenSSL::SSL::SSLSocket]
container[R]
@return [Thread]
control_r[R]
@return [IO]
control_w[R]
@return [IO]
die[R]
@return [TrueClass, FalseClass]
handshake[R]
@return [WebSocket::Handshake::Client]
Public Class Methods
new(args={})
click to toggle source
Create a new websocket client
@return [self]
# File lib/bogo-websocket/websocket.rb, line 45 def initialize(args={}) load_data(args) @control_r, @control_w = IO.pipe @die = false setup_connection perform_handshake @lock = Mutex.new @container = start! end
Public Instance Methods
build_ssl_context()
click to toggle source
@return [OpenSSL::SSL::SSLContext]
# File lib/bogo-websocket/websocket.rb, line 169 def build_ssl_context if(ssl_context) ssl_context else ctx = OpenSSL::SSL::SSLContext.new if(ssl_key || ssl_certificate) ctx.cert = OpenSSL::X509::Certificate.new(File.read(ssl_certificate)) ctx.key = OpenSSL::PKey::RSA.new(File.read(ssl_key)) end ctx end end
close()
click to toggle source
Close the connection
# File lib/bogo-websocket/websocket.rb, line 63 def close if(connection) connection.close @die = true control_w.write 'closed' container.join unless Thread.current == container @connection = nil end end
handle_message(message)
click to toggle source
Handle an incoming message
@param message [WebSocket::Frame::Incoming::Client]
# File lib/bogo-websocket/websocket.rb, line 102 def handle_message(message) case message.type when :binary, :text on_message.call(message.data) when :ping transmit(message.data, :pong) when :close connection.close on_disconnect.call end end
perform_handshake()
click to toggle source
Setup the handshake and perform handshake with remote connection
@return [TrueClass]
# File lib/bogo-websocket/websocket.rb, line 132 def perform_handshake port = destination.port || destination.scheme == 'wss' ? 443 : 80 @handshake = WebSocket::Handshake::Client.new( :host => destination.host, :port => port, :secure => destination.scheme == 'wss', :path => path, :query => URI.encode_www_form(params), :headers => headers ) connection.write handshake.to_s reply = '' until(handshake.finished?) reply << connection.read(1) if(reply.index(/\r\n\r\n/m)) handshake << reply reply = '' end end unless(handshake.valid?) raise ArgumentError.new 'Invalid handshake. Failed to connect!' end @client = WebSocket::Frame::Incoming::Client.new(:version => handshake.version) true end
setup_connection()
click to toggle source
@return [TCPSocket, OpenSSL::SSL::SSLSocket]
# File lib/bogo-websocket/websocket.rb, line 159 def setup_connection socket = TCPSocket.new(destination.host, destination.port) if(destination.scheme == 'wss') socket = OpenSSL::SSL::SSLSocket.new(socket, build_ssl_context) socket.connect end @connection = socket end
start!()
click to toggle source
Start the reader
# File lib/bogo-websocket/websocket.rb, line 74 def start! unless(@container) @container = Thread.new do until(die || connection.closed?) begin unless(die || connection.closed?) client << connection.read_nonblock(1024) if(message = client.next) handle_message(message) end end rescue IO::WaitReadable, Errno::EAGAIN => e unless(die || connection.closed?) IO.select([connection, control_r]) retry end rescue => error on_error.call(error) close end end end end end
transmit(data, type)
click to toggle source
Send data to socket
@param data [String] @param type [Symbol]
# File lib/bogo-websocket/websocket.rb, line 118 def transmit(data, type) message = WebSocket::Frame::Outgoing::Client.new( :version => handshake.version, :data => data, :type => type ) result = connection.write message.to_s connection.flush result end
write(line)
click to toggle source
Write to socket
@param line [String]
# File lib/bogo-websocket/websocket.rb, line 58 def write(line) transmit(line, :text) end