Class: WebsocketSequentialClient::WebSocket
- Inherits:
-
Object
- Object
- WebsocketSequentialClient::WebSocket
- Defined in:
- lib/websocket_sequential_client/web_socket.rb
Overview
This class provides the access to a WebSocket server.
Constant Summary collapse
- DEFAULT_PING_INTERVAL =
20- DEFAULT_CLOSE_CODE =
1000- DEFAULT_CLOSE_TIMEOUT =
20- RECV_SIZE =
:nodoc:
1024- WS_PORT =
:nodoc:
80
Instance Attribute Summary collapse
-
#close_code ⇒ Object
readonly
Returns the value of attribute close_code.
-
#close_reason ⇒ Object
readonly
Returns the value of attribute close_reason.
Class Method Summary collapse
-
.open(*args, &block) ⇒ Object
Connects to a WebSocket server and returns the connected socket.
Instance Method Summary collapse
-
#available? ⇒ Boolean
(also: #data_available?)
Returns true if a received data is in the internal buffer.
-
#close(code = nil, reason = nil, opt = {}) ⇒ Object
Close the socket.
-
#initialize(url, opt = {}) ⇒ WebSocket
constructor
Connects to a WebSocket server and returns the connected socket.
-
#recv ⇒ Object
(also: #receive)
Returns a received data from the server.
-
#send(data, type = :guess) ⇒ Object
Sends a data to the server.
-
#send_binary(data) ⇒ Object
Sends a binary message.
-
#send_text(data) ⇒ Object
Sends a text message.
Constructor Details
#initialize(url, opt = {}) ⇒ WebSocket
Connects to a WebSocket server and returns the connected socket.
Parameters
url-
URL of the server.
opt-
Optional hash parameters.
:pingkey specifies whether to enable automatic ping. You can settrue,falseor{ interval: 10 }. The default value istrue.:headerskey specifies the additional HTTP headers. You can set{ headers: { "Cookie" => "name=value" } }. The default value is{}(empty hash).
Examples
# Connect to the server.
ws = WebSocketSequentialClient::WebSocket.new "ws://server-url"
# Disable automatic ping.
ws = WebSocketSequentialClient::WebSocket.new "ws://server-url", ping: false
# Set the ping interval to 10s and send additional HTTP headers.
opt = { ping: { interval: 10 }, headers: { "Cookie" => "name=value", "Header" => "Value" } }
ws = WebSocketSequentialClient::WebSocket.open "ws://server-url", opt
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 75 def initialize url, opt = {} opt = { ping: true, headers: {} }.merge opt @read_queue = ReadQueue.new @write_queue = WriteQueue.new @closed_status_mutex = Mutex.new @closed_status_cond_var = ConditionVariable.new @closed_status = nil @close_timeout = DEFAULT_CLOSE_TIMEOUT @close_code = nil @close_reason = nil @ping_th = nil url = URI.parse url.to_s unless url.kind_of? URI @url = url case url.scheme when "ws" @socket = TCPSocket.new(url.host, url.port || WS_PORT) else raise ArgumentError, "URL scheme must be 'ws'." end hs = handshake(opt[:headers]) @version = hs.version Thread.start{ send_background } Thread.start{ receive_background } start_ping_thread opt[:ping] if opt[:ping] rescue close_socket(SocketAlreadyClosed.new, SocketAlreadyClosed.new) raise end |
Instance Attribute Details
#close_code ⇒ Object (readonly)
Returns the value of attribute close_code.
113 114 115 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 113 def close_code @close_code end |
#close_reason ⇒ Object (readonly)
Returns the value of attribute close_reason.
113 114 115 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 113 def close_reason @close_reason end |
Class Method Details
.open(*args, &block) ⇒ Object
Connects to a WebSocket server and returns the connected socket.
Parameters
args-
See
initializemethod. block-
If given, it will be called with the instance of WebSocket as the argument.
Examples
WebSocketSequentialClient::WebSocket.open "ws://server-url" do |ws|
ws.send "message"
puts ws.recv
end
ws = WebSocketSequentialClient::WebSocket.open "ws://server-url"
ws.send "message"
puts ws.recv
ws.close
WebSocketSequentialClient::WebSocket.open "ws://server-url", { ping: false } do |ws|
ws.send "message"
puts ws.recv
end
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 42 def self.open *args, &block if block ws = self.new *args begin block.call ws ensure ws.close end else self.new *args end end |
Instance Method Details
#available? ⇒ Boolean Also known as: data_available?
Returns true if a received data is in the internal buffer.
118 119 120 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 118 def available? @read_queue.available? end |
#close(code = nil, reason = nil, opt = {}) ⇒ Object
Close the socket.
Parameters
code-
Code of the close frame. The default value is 1000.
reason-
The reason of the close frame. The default value is nil.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 201 def close code = nil, reason = nil, opt = {} code ||= DEFAULT_CLOSE_CODE opt = { timeout: DEFAULT_CLOSE_TIMEOUT, wait_for_response: true }.merge opt param = { code: code, type: :close, version: @version } param[:data] = reason if reason frame = ::WebSocket::Frame::Outgoing::Client.new(param) @close_timeout = opt[:timeout] @write_queue.process_frame frame wait_for_response = opt[:wait_for_response] if wait_for_response @closed_status_mutex.synchronize do @closed_status_cond_var.wait @closed_status_mutex until @closed_status == :closed end end end |
#recv ⇒ Object Also known as: receive
Returns a received data from the server. The encoding of the returned data is “UTF-8” for text messages, “ASCII-8BIT” for binary messages.
This is a blocking method. i.e. This method is blocked until a data is received from the server.
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 129 def recv data = @read_queue.pop raise data if data.kind_of? StandardError case data.type when :text data.to_s.force_encoding Encoding::UTF_8 when :binary data.to_s.force_encoding Encoding::BINARY else raise NotImplementedError end end |
#send(data, type = :guess) ⇒ Object
Sends a data to the server.
Parameters
data-
String to be sent. The encoding should be “UTF-8” for text messages, “ASCII-8BIT” for binary messages.
type-
Specifies
:text,:binaryor:guess. If:guessis specified, the type is guessed based on the encoding ofdata.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 151 def send data, type = :guess case type when :guess if data.encoding == Encoding::BINARY type = :binary elsif Encoding.compatible?(data.encoding, Encoding::UTF_8) type = :text else raise ArgumentError, "Invalid encoding." end when :text unless Encoding.compatible?(data.encoding, Encoding::UTF_8) raise ArgumentError, "Invalid encoding" end when :binary # else raise ArgumentError, "Invalid type specified" end # data.b is necessary for the current implementation of websocket gem library. frame = ::WebSocket::Frame::Outgoing::Client.new(data: data.b, type: type, version: @version) result = @write_queue.process_frame frame raise result if result.kind_of? StandardError end |
#send_binary(data) ⇒ Object
Sends a binary message. Same as send data, :binary.
190 191 192 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 190 def send_binary data send data, :binary end |
#send_text(data) ⇒ Object
Sends a text message. Same as send data, :text.
182 183 184 |
# File 'lib/websocket_sequential_client/web_socket.rb', line 182 def send_text data send data, :text end |