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