Class: WebsocketTD::Websocket
- Inherits:
-
Object
- Object
- WebsocketTD::Websocket
- Defined in:
- lib/websocket_td.rb
Instance Attribute Summary collapse
-
#active ⇒ Object
readonly
Returns the value of attribute active.
-
#auto_pong ⇒ Object
Returns the value of attribute auto_pong.
-
#on_error ⇒ Object
writeonly
:on_open, :on_close.
-
#on_message ⇒ Object
writeonly
:on_open, :on_close.
-
#on_ping ⇒ Object
writeonly
:on_open, :on_close.
-
#read_buffer ⇒ Object
Returns the value of attribute read_buffer.
-
#read_thread ⇒ Object
readonly
Returns the value of attribute read_thread.
-
#socket ⇒ Object
readonly
Returns the value of attribute socket.
Instance Method Summary collapse
- #determine_message_type(message) ⇒ Object
- #fire_on_close(message = nil) ⇒ Object
- #fire_on_error(error) ⇒ Object
- #fire_on_message(message) ⇒ Object
- #fire_on_open ⇒ Object
- #fire_on_ping(message) ⇒ Object
-
#init_messaging ⇒ Object
Use one thread to perform blocking read on the socket.
-
#initialize(host, path, query, secure = false, port = nil) ⇒ Websocket
constructor
host-
Host of request.
- #on_close=(p) ⇒ Object
- #on_open=(p) ⇒ Object
- #read_loop ⇒ Object
- #send(data, type = :text) ⇒ Object
Constructor Details
#initialize(host, path, query, secure = false, port = nil) ⇒ Websocket
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.
port-
Port of request. Default: nil
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/websocket_td.rb', line 20 def initialize(host, path, query, secure = false, port = nil) if port == nil port = secure ? 443 : 80 end @handshake = WebSocket::Handshake::Client.new({ :host => host, :port => port, :secure => secure, :path => path, :query => query }) @read_buffer = 2048 @auto_pong = true @closed = false @opened = false @on_open = lambda {} @on_close = lambda { ||} @on_ping = lambda { ||} @on_error = lambda { |error|} @on_message = lambda { ||} tcp_socket = TCPSocket.new(host, port) if secure @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket) @socket.connect else @socket = tcp_socket end @socket.write @handshake.to_s buf = '' headers = '' reading = true while reading begin if @handshake.finished? init_messaging #don't stop reading until after init_message to guarantee @read_thread != nil for a successful connection reading = false @opened =true fire_on_open else #do non blocking reads on headers - 1 byte at a time buf.concat(@socket.read_nonblock(1)) #\r\n\r\n i.e. a blank line, separates headers from body idx = buf.index(/\r\n\r\n/m) if idx != nil headers = buf.slice!(0..idx + 8) #+8 to include the blank line separator @handshake << headers #parse headers if @handshake.finished? && !@handshake.valid? fire_on_error(ConnectError.new('Server responded with an invalid handshake')) fire_on_close() #close if handshake is not valid end if @handshake.finished? @active = true buf = '' #clean up headers = '' end end end rescue IO::WaitReadable # ignored rescue IO::WaitWritable # ignored end end puts headers end |
Instance Attribute Details
#active ⇒ Object (readonly)
Returns the value of attribute active.
95 96 97 |
# File 'lib/websocket_td.rb', line 95 def active @active end |
#auto_pong ⇒ Object
Returns the value of attribute auto_pong.
95 96 97 |
# File 'lib/websocket_td.rb', line 95 def auto_pong @auto_pong end |
#on_error=(value) ⇒ Object (writeonly)
:on_open, :on_close
96 97 98 |
# File 'lib/websocket_td.rb', line 96 def on_error=(value) @on_error = value end |
#on_message=(value) ⇒ Object (writeonly)
:on_open, :on_close
96 97 98 |
# File 'lib/websocket_td.rb', line 96 def (value) @on_message = value end |
#on_ping=(value) ⇒ Object (writeonly)
:on_open, :on_close
96 97 98 |
# File 'lib/websocket_td.rb', line 96 def on_ping=(value) @on_ping = value end |
#read_buffer ⇒ Object
Returns the value of attribute read_buffer.
95 96 97 |
# File 'lib/websocket_td.rb', line 95 def read_buffer @read_buffer end |
#read_thread ⇒ Object (readonly)
Returns the value of attribute read_thread.
95 96 97 |
# File 'lib/websocket_td.rb', line 95 def read_thread @read_thread end |
#socket ⇒ Object (readonly)
Returns the value of attribute socket.
95 96 97 |
# File 'lib/websocket_td.rb', line 95 def socket @socket end |
Instance Method Details
#determine_message_type(message) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/websocket_td.rb', line 137 def () if .type == :binary || .type == :text () elsif .type == :ping if @auto_pong send(.data, :pong) end fire_on_ping() elsif .type == :pong fire_on_error(WsProtocolError.new('Invalid type pong received')) elsif .type == :close fire_on_close() else fire_on_error(BadMessageTypeError.new("An unknown message type was received #{.data}")) end end |
#fire_on_close(message = nil) ⇒ Object
184 185 186 187 188 189 |
# File 'lib/websocket_td.rb', line 184 def fire_on_close( = nil) @active = false @closed = true @on_close.call() unless @on_close == nil @socket.close end |
#fire_on_error(error) ⇒ Object
180 181 182 |
# File 'lib/websocket_td.rb', line 180 def fire_on_error(error) @on_error.call(error) unless @on_error == nil end |
#fire_on_message(message) ⇒ Object
172 173 174 |
# File 'lib/websocket_td.rb', line 172 def () @on_message.call() unless @on_message == nil end |
#fire_on_open ⇒ Object
176 177 178 |
# File 'lib/websocket_td.rb', line 176 def fire_on_open @on_open.call() unless @on_open == nil end |
#fire_on_ping(message) ⇒ Object
168 169 170 |
# File 'lib/websocket_td.rb', line 168 def fire_on_ping() @on_ping.call() unless @on_ping == nil end |
#init_messaging ⇒ Object
Use one thread to perform blocking read on the socket
113 114 115 116 117 118 119 |
# File 'lib/websocket_td.rb', line 113 def init_messaging if @read_thread == nil @read_thread = Thread.new do read_loop end end end |
#on_close=(p) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/websocket_td.rb', line 105 def on_close=(p) @on_close = p if @closed fire_on_close end end |
#on_open=(p) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/websocket_td.rb', line 98 def on_open=(p) @on_open = p if @opened fire_on_open end end |
#read_loop ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/websocket_td.rb', line 121 def read_loop frame = WebSocket::Frame::Incoming::Client.new(:version => @handshake.version) while @active if @socket.closed? @active = false fire_on_close else frame << @socket.readpartial(@read_buffer) if ( = frame.next) != nil #"text", "binary", "ping", "pong" and "close" (according to websocket/base.rb) () end end end end |
#send(data, type = :text) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/websocket_td.rb', line 155 def 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 fire_on_error(ce) fire_on_close rescue Exception => e fire_on_error(e) end end |