lib/websocket_td.rb in websocket-td-0.0.2 vs lib/websocket_td.rb in websocket-td-0.0.3

- old
+ new

@@ -2,17 +2,19 @@ require 'socket' require '../lib/errors' module WebsocketTD class Websocket + IS_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) # max length bytes to try to read from a socket per attempt @read_buffer = 0 #true when reading data from a socket @active = false #the tread currently being used to read data @read_thread = nil @auto_pong = true + ## # +host+:: Host of request. Required if no :url param was provided. # +path+:: Path of request. Should start with '/'. Default: '/' # +query+:: Query for request. Should be in format "aaa=bbb&ccc=ddd" # +secure+:: Defines protocol to use. If true then wss://, otherwise ws://. This option will not change default port - it should be handled by programmer. @@ -46,11 +48,55 @@ @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket) @socket.connect else @socket = tcp_socket end + perform_handshake + end + attr_reader :read_thread, :read_buffer, :socket, :active, :auto_pong + attr_writer :read_buffer, :auto_pong, :on_ping, :on_error, :on_message # :on_open, :on_close + + ## + #Send the data given by the data param + #if running on a posix system this uses Ruby's fork method to send + #if on windows fork won't be attempted. + #+data+:: the data to send + #+type+:: :text or :binary, defaults to :text + def send(data, type = :text) + if IS_WINDOWS + do_send(data, type) #fork not supported on windows + else + fork do + do_send(data, type) + end + end + end + + ## + #sets a Proc to be executed when the connection is opened and ready for writing + #+p+:: the Proc to execute + def on_open=(p) + @on_open = p + if @opened + fire_on_open + end + end + + ## + #sets a Proc to be executed when the connection is closed and ready for writing + #+p+:: the Proc to execute + def on_close=(p) + @on_close = p + if @closed + fire_on_close + end + end + +#protected methods after this + protected + def perform_handshake @socket.write @handshake.to_s buf = '' headers = '' reading = true @@ -87,30 +133,12 @@ # ignored rescue IO::WaitWritable # ignored end end - puts headers end - attr_reader :read_thread, :read_buffer, :socket, :active, :auto_pong - attr_writer :read_buffer, :auto_pong, :on_ping, :on_error, :on_message # :on_open, :on_close - - def on_open=(p) - @on_open = p - if @opened - fire_on_open - end - end - - def on_close=(p) - @on_close = p - if @closed - fire_on_close - end - end - #Use one thread to perform blocking read on the socket def init_messaging if @read_thread == nil @read_thread = Thread.new do read_loop @@ -123,14 +151,19 @@ while @active if @socket.closed? @active = false fire_on_close else - frame << @socket.readpartial(@read_buffer) - if (message = frame.next) != nil - #"text", "binary", "ping", "pong" and "close" (according to websocket/base.rb) - determine_message_type(message) + begin + frame << @socket.readpartial(@read_buffer) + if (message = frame.next) != nil + #"text", "binary", "ping", "pong" and "close" (according to websocket/base.rb) + determine_message_type(message) + end + rescue EOFError => eof + fire_on_error(eof) + fire_on_close end end end end @@ -149,11 +182,10 @@ else fire_on_error(BadMessageTypeError.new("An unknown message type was received #{message.data}")) end end - - def send(data, type = :text) + def do_send(data, type=:text) frame = WebSocket::Frame::Outgoing::Client.new(:version => @handshake.version, :data => data, :type => type) begin @socket.write frame #_nonblock @socket.flush rescue Errno::EPIPE => ce \ No newline at end of file