websocket_sequential_client 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/README.md +3 -1
- data/lib/websocket_sequential_client.rb +1 -0
- data/lib/websocket_sequential_client/exception.rb +12 -0
- data/lib/websocket_sequential_client/read_queue.rb +1 -1
- data/lib/websocket_sequential_client/version.rb +1 -1
- data/lib/websocket_sequential_client/web_socket.rb +94 -9
- data/lib/websocket_sequential_client/write_queue.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a9cdfa2ccc4b1defa9165cfeddf1ec01abf7825
|
4
|
+
data.tar.gz: c35dea58c8e676a4642500210ac907d605e9b9cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86696686c0fcd88d2e7e076a87a2800544b2df30c0d24c04791fc2008364ebeb9ad60f55cef242d26aa34d50eaa7fc5463531acb2a98820a18ad800d09d4af8e
|
7
|
+
data.tar.gz: 01c5186f40dd70ae8f2cd3dfb6e1e9ad278cda60743cbc5abcdffbda4e4daf75847243b5f818f349923e44b43b78950205928ff67f4c4cebb2d68df7a5adf203
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# WebSocketSequentialClient [](http://badge.fury.io/rb/websocket_sequential_client) [](https://travis-ci.org/masamitsu-murase/websocket_sequential_client)
|
2
2
|
|
3
3
|
This ruby gem library allows you to access a WebSocket server in a **sequential** way instead of an event-driven way.
|
4
4
|
|
@@ -122,6 +122,8 @@ ws.close
|
|
122
122
|
|
123
123
|
## Versions
|
124
124
|
|
125
|
+
* 1.0.1
|
126
|
+
Fix handling of optional parameters.
|
125
127
|
* 1.0.0
|
126
128
|
Initial release
|
127
129
|
|
@@ -1,15 +1,27 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
module WebsocketSequentialClient
|
4
|
+
#
|
5
|
+
# Base errror class
|
6
|
+
#
|
4
7
|
class Error < StandardError
|
5
8
|
end
|
6
9
|
|
10
|
+
#
|
11
|
+
# This error is raised when <tt>recv</tt> or <tt>send</tt> is called after the socket is closed.
|
12
|
+
#
|
7
13
|
class SocketAlreadyClosed < Error
|
8
14
|
end
|
9
15
|
|
16
|
+
#
|
17
|
+
# This error is raised when handshake with a server failed.
|
18
|
+
#
|
10
19
|
class HandshakeFailed < Error
|
11
20
|
end
|
12
21
|
|
22
|
+
#
|
23
|
+
# This error is raised when a invaid data is received.
|
24
|
+
#
|
13
25
|
class InvalidDataReceived < Error
|
14
26
|
end
|
15
27
|
end
|
@@ -4,15 +4,41 @@ require("socket")
|
|
4
4
|
require("thread")
|
5
5
|
|
6
6
|
module WebsocketSequentialClient
|
7
|
+
#
|
8
|
+
# This class provides the access to a WebSocket server.
|
9
|
+
#
|
7
10
|
class WebSocket
|
8
11
|
DEFAULT_PING_INTERVAL = 20
|
9
12
|
DEFAULT_CLOSE_CODE = 1000
|
10
13
|
DEFAULT_CLOSE_TIMEOUT = 20
|
11
14
|
|
12
|
-
RECV_SIZE = 1024
|
13
|
-
|
14
|
-
WS_PORT = 80
|
15
|
-
|
15
|
+
RECV_SIZE = 1024 #:nodoc:
|
16
|
+
|
17
|
+
WS_PORT = 80 #:nodoc:
|
18
|
+
|
19
|
+
#
|
20
|
+
# Connects to a WebSocket server and returns the connected socket.
|
21
|
+
#
|
22
|
+
# === Parameters
|
23
|
+
# +args+ :: See <tt>initialize</tt> method.
|
24
|
+
# +block+ :: If given, it will be called with the instance of WebSocket as the argument.
|
25
|
+
#
|
26
|
+
# === Examples
|
27
|
+
# WebSocketSequentialClient::WebSocket.open "ws://server-url" do |ws|
|
28
|
+
# ws.send "message"
|
29
|
+
# puts ws.recv
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# ws = WebSocketSequentialClient::WebSocket.open "ws://server-url"
|
33
|
+
# ws.send "message"
|
34
|
+
# puts ws.recv
|
35
|
+
# ws.close
|
36
|
+
#
|
37
|
+
# WebSocketSequentialClient::WebSocket.open "ws://server-url", { ping: false } do |ws|
|
38
|
+
# ws.send "message"
|
39
|
+
# puts ws.recv
|
40
|
+
# end
|
41
|
+
#
|
16
42
|
def self.open *args, &block
|
17
43
|
if block
|
18
44
|
ws = self.new *args
|
@@ -26,7 +52,29 @@ module WebsocketSequentialClient
|
|
26
52
|
end
|
27
53
|
end
|
28
54
|
|
29
|
-
|
55
|
+
#
|
56
|
+
# Connects to a WebSocket server and returns the connected socket.
|
57
|
+
#
|
58
|
+
# === Parameters
|
59
|
+
# +url+ :: URL of the server.
|
60
|
+
# +opt+ :: Optional hash parameters.
|
61
|
+
# <tt>:ping</tt> key specifies whether to enable automatic ping. You can set <tt>true</tt>, <tt>false</tt> or <tt>{ interval: 10 }</tt>. The default value is <tt>true</tt>.
|
62
|
+
# <tt>:headers</tt> key specifies the additional HTTP headers. You can set <tt>{ headers: { "Cookie" => "name=value" } }</tt>. The default value is <tt>{}</tt> (empty hash).
|
63
|
+
#
|
64
|
+
# === Examples
|
65
|
+
# # Connect to the server.
|
66
|
+
# ws = WebSocketSequentialClient::WebSocket.new "ws://server-url"
|
67
|
+
#
|
68
|
+
# # Disable automatic ping.
|
69
|
+
# ws = WebSocketSequentialClient::WebSocket.new "ws://server-url", ping: false
|
70
|
+
#
|
71
|
+
# # Set the ping interval to 10s and send additional HTTP headers.
|
72
|
+
# opt = { ping: { interval: 10 }, headers: { "Cookie" => "name=value", "Header" => "Value" } }
|
73
|
+
# ws = WebSocketSequentialClient::WebSocket.open "ws://server-url", opt
|
74
|
+
#
|
75
|
+
def initialize url, opt = {}
|
76
|
+
opt = { ping: true, headers: {} }.merge opt
|
77
|
+
|
30
78
|
@read_queue = ReadQueue.new
|
31
79
|
@write_queue = WriteQueue.new
|
32
80
|
|
@@ -64,11 +112,20 @@ module WebsocketSequentialClient
|
|
64
112
|
end
|
65
113
|
attr_reader :close_code, :close_reason
|
66
114
|
|
115
|
+
#
|
116
|
+
# Returns true if a received data is in the internal buffer.
|
117
|
+
#
|
67
118
|
def available?
|
68
119
|
@read_queue.available?
|
69
120
|
end
|
70
121
|
alias data_available? available?
|
71
122
|
|
123
|
+
#
|
124
|
+
# Returns a received data from the server.
|
125
|
+
# The encoding of the returned data is "UTF-8" for text messages, "ASCII-8BIT" for binary messages.
|
126
|
+
#
|
127
|
+
# This is a <b>blocking</b> method. i.e. This method is blocked until a data is received from the server.
|
128
|
+
#
|
72
129
|
def recv
|
73
130
|
data = @read_queue.pop
|
74
131
|
raise data if data.kind_of? StandardError
|
@@ -84,6 +141,13 @@ module WebsocketSequentialClient
|
|
84
141
|
end
|
85
142
|
alias receive recv
|
86
143
|
|
144
|
+
#
|
145
|
+
# Sends a data to the server.
|
146
|
+
#
|
147
|
+
# === Parameters
|
148
|
+
# +data+ :: String to be sent. The encoding should be "UTF-8" for text messages, "ASCII-8BIT" for binary messages.
|
149
|
+
# +type+ :: Specifies <tt>:text</tt>, <tt>:binary</tt> or <tt>:guess</tt>. If <tt>:guess</tt> is specified, the type is guessed based on the encoding of <tt>data</tt>.
|
150
|
+
#
|
87
151
|
def send data, type = :guess
|
88
152
|
case type
|
89
153
|
when :guess
|
@@ -111,16 +175,33 @@ module WebsocketSequentialClient
|
|
111
175
|
raise result if result.kind_of? StandardError
|
112
176
|
end
|
113
177
|
|
178
|
+
#
|
179
|
+
# Sends a text message.
|
180
|
+
# Same as <tt>send data, :text</tt>.
|
181
|
+
#
|
114
182
|
def send_text data
|
115
183
|
send data, :text
|
116
184
|
end
|
117
185
|
|
186
|
+
#
|
187
|
+
# Sends a binary message.
|
188
|
+
# Same as <tt>send data, :binary</tt>.
|
189
|
+
#
|
118
190
|
def send_binary data
|
119
191
|
send data, :binary
|
120
192
|
end
|
121
193
|
|
122
|
-
|
194
|
+
#
|
195
|
+
# Close the socket.
|
196
|
+
#
|
197
|
+
# === Parameters
|
198
|
+
# +code+ :: Code of the close frame. The default value is 1000.
|
199
|
+
# +reason+ :: The reason of the close frame. The default value is nil.
|
200
|
+
#
|
201
|
+
def close code = nil, reason = nil, opt = {}
|
123
202
|
code ||= DEFAULT_CLOSE_CODE
|
203
|
+
opt = { timeout: DEFAULT_CLOSE_TIMEOUT, wait_for_response: true }.merge opt
|
204
|
+
|
124
205
|
param = {
|
125
206
|
code: code,
|
126
207
|
type: :close,
|
@@ -129,10 +210,10 @@ module WebsocketSequentialClient
|
|
129
210
|
param[:data] = reason if reason
|
130
211
|
frame = ::WebSocket::Frame::Outgoing::Client.new(param)
|
131
212
|
|
132
|
-
@close_timeout =
|
213
|
+
@close_timeout = opt[:timeout]
|
133
214
|
@write_queue.process_frame frame
|
134
215
|
|
135
|
-
wait_for_response =
|
216
|
+
wait_for_response = opt[:wait_for_response]
|
136
217
|
if wait_for_response
|
137
218
|
@closed_status_mutex.synchronize do
|
138
219
|
@closed_status_cond_var.wait @closed_status_mutex until @closed_status == :closed
|
@@ -158,7 +239,11 @@ module WebsocketSequentialClient
|
|
158
239
|
end
|
159
240
|
|
160
241
|
def start_ping_thread ping_opt
|
161
|
-
|
242
|
+
if ping_opt == true
|
243
|
+
interval = DEFAULT_PING_INTERVAL
|
244
|
+
else
|
245
|
+
interval = (ping_opt[:interval] || DEFAULT_PING_INTERVAL)
|
246
|
+
end
|
162
247
|
raise ArgumentError, "opt[:ping][:interval] must be a positive number." if interval <= 0
|
163
248
|
@ping_th = Thread.start(interval) do |i|
|
164
249
|
while true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: websocket_sequential_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masamitsu MURASE
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: websocket
|