websocket_sequential_client 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Gem Version](https://badge.fury.io/rb/websocket_sequential_client.svg)](http://badge.fury.io/rb/websocket_sequential_client) [![Build Status](https://travis-ci.org/masamitsu-murase/websocket_sequential_client.svg)](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
|