xrbp 0.0.1 → 0.1.0
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/README.md +103 -5
- data/examples/accounts.rb +13 -0
- data/examples/autoconnect_timeout.rb +5 -1
- data/examples/autorety.rb +7 -0
- data/examples/crawl_nodes.rb +32 -0
- data/examples/dsl/account.rb +16 -0
- data/examples/dsl/ledger.rb +7 -0
- data/examples/dsl/ledger_subscribe.rb +18 -0
- data/examples/dsl/validators.rb +8 -0
- data/examples/gateways.rb +8 -0
- data/examples/latest_account.rb +4 -0
- data/examples/ledger_multi_subscribe.rb +1 -1
- data/examples/ledger_subscribe.rb +2 -2
- data/examples/market.rb +13 -0
- data/examples/username.rb +12 -0
- data/examples/validator.rb +8 -0
- data/lib/xrbp.rb +5 -1
- data/lib/xrbp/common.rb +10 -0
- data/lib/xrbp/core_ext.rb +24 -0
- data/lib/xrbp/dsl.rb +25 -0
- data/lib/xrbp/dsl/accounts.rb +13 -0
- data/lib/xrbp/dsl/ledgers.rb +23 -0
- data/lib/xrbp/dsl/validators.rb +10 -0
- data/lib/xrbp/dsl/webclient.rb +8 -0
- data/lib/xrbp/dsl/websocket.rb +28 -0
- data/lib/xrbp/model.rb +4 -0
- data/lib/xrbp/model/account.rb +142 -1
- data/lib/xrbp/model/base.rb +1 -0
- data/lib/xrbp/model/gateway.rb +24 -0
- data/lib/xrbp/model/ledger.rb +30 -1
- data/lib/xrbp/model/market.rb +52 -0
- data/lib/xrbp/model/node.rb +131 -0
- data/lib/xrbp/model/parsers/account.rb +44 -0
- data/lib/xrbp/model/parsers/gateway.rb +40 -0
- data/lib/xrbp/model/parsers/market.rb +28 -0
- data/lib/xrbp/model/parsers/node.rb +19 -0
- data/lib/xrbp/model/parsers/quote.rb +47 -0
- data/lib/xrbp/model/parsers/validator.rb +25 -0
- data/lib/xrbp/model/validator.rb +24 -0
- data/lib/xrbp/plugins.rb +6 -0
- data/lib/xrbp/plugins/base.rb +10 -0
- data/lib/xrbp/plugins/has_plugin.rb +45 -0
- data/lib/xrbp/plugins/has_result_parsers.rb +27 -0
- data/lib/xrbp/plugins/plugin_registry.rb +20 -0
- data/lib/xrbp/plugins/result_parser.rb +19 -0
- data/lib/xrbp/terminatable.rb +19 -0
- data/lib/xrbp/thread_registry.rb +22 -0
- data/lib/xrbp/version.rb +1 -1
- data/lib/xrbp/webclient.rb +2 -0
- data/lib/xrbp/webclient/connection.rb +100 -0
- data/lib/xrbp/webclient/plugins.rb +8 -0
- data/lib/xrbp/webclient/plugins/autoretry.rb +54 -0
- data/lib/xrbp/webclient/plugins/result_parser.rb +23 -0
- data/lib/xrbp/websocket/client.rb +85 -24
- data/lib/xrbp/websocket/cmds/account_info.rb +4 -0
- data/lib/xrbp/websocket/cmds/account_lines.rb +5 -0
- data/lib/xrbp/websocket/cmds/account_objects.rb +4 -0
- data/lib/xrbp/websocket/cmds/account_offers.rb +5 -0
- data/lib/xrbp/websocket/cmds/account_tx.rb +4 -0
- data/lib/xrbp/websocket/cmds/book_offers.rb +4 -0
- data/lib/xrbp/websocket/cmds/ledger.rb +3 -0
- data/lib/xrbp/websocket/cmds/ledger_entry.rb +4 -0
- data/lib/xrbp/websocket/cmds/paginated.rb +4 -1
- data/lib/xrbp/websocket/cmds/server_info.rb +4 -0
- data/lib/xrbp/websocket/cmds/subscribe.rb +4 -0
- data/lib/xrbp/websocket/command.rb +11 -0
- data/lib/xrbp/websocket/connection.rb +75 -22
- data/lib/xrbp/websocket/message.rb +5 -2
- data/lib/xrbp/websocket/multi/fallback.rb +2 -4
- data/lib/xrbp/websocket/multi/multi_connection.rb +37 -2
- data/lib/xrbp/websocket/multi/parallel.rb +2 -4
- data/lib/xrbp/websocket/multi/prioritized.rb +2 -4
- data/lib/xrbp/websocket/multi/round_robin.rb +4 -0
- data/lib/xrbp/websocket/plugins.rb +1 -7
- data/lib/xrbp/websocket/plugins/autoconnect.rb +25 -5
- data/lib/xrbp/websocket/plugins/command_dispatcher.rb +5 -0
- data/lib/xrbp/websocket/plugins/command_paginator.rb +9 -8
- data/lib/xrbp/websocket/plugins/connection_timeout.rb +27 -16
- data/lib/xrbp/websocket/plugins/message_dispatcher.rb +60 -30
- data/lib/xrbp/websocket/plugins/result_parser.rb +19 -19
- data/lib/xrbp/websocket/socket.rb +23 -6
- metadata +118 -8
- data/lib/xrbp/network.rb +0 -6
- data/lib/xrbp/network/nodes.rb +0 -8
- data/lib/xrbp/websocket/has_plugin.rb +0 -30
@@ -0,0 +1,54 @@
|
|
1
|
+
module XRBP
|
2
|
+
module WebClient
|
3
|
+
module Plugins
|
4
|
+
# Plugin to automatically retry WebClient Connection requests
|
5
|
+
# multiple times.
|
6
|
+
#
|
7
|
+
# If no max_tries are specified, requests will be tried indefinitely.
|
8
|
+
# Optionally configured interval to wait between retries.
|
9
|
+
#
|
10
|
+
# @example retrying request:
|
11
|
+
# connection = WebClient::Connection.new
|
12
|
+
# connection.add_plugin :autoretry
|
13
|
+
#
|
14
|
+
# connection.max_tries = 3
|
15
|
+
# connection.interval = 1
|
16
|
+
# connection.timeout = 1
|
17
|
+
#
|
18
|
+
# connection.url = "http://doesnt.exist"
|
19
|
+
# connection.perform
|
20
|
+
class AutoRetry < PluginBase
|
21
|
+
attr_accessor :interval, :max_tries
|
22
|
+
|
23
|
+
def initialize(connection)
|
24
|
+
super(connection)
|
25
|
+
@interval = 3
|
26
|
+
@max_tries = nil
|
27
|
+
@retry_num = 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def added
|
31
|
+
plugin = self
|
32
|
+
connection.define_instance_method(:retry_interval=) do |i|
|
33
|
+
plugin.interval = i
|
34
|
+
end
|
35
|
+
|
36
|
+
connection.define_instance_method(:max_retries=) do |i|
|
37
|
+
plugin.max_tries = i
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_error
|
42
|
+
@retry_num += 1
|
43
|
+
return nil if connection.force_quit? ||
|
44
|
+
(!@max_tries.nil? && @retry_num > @max_tries)
|
45
|
+
|
46
|
+
connection.rsleep(@interval)
|
47
|
+
connection.perform
|
48
|
+
end
|
49
|
+
end # class AutoRetry
|
50
|
+
|
51
|
+
WebClient.register_plugin :autoretry, AutoRetry
|
52
|
+
end # module Plugins
|
53
|
+
end # module WebClient
|
54
|
+
end # module XRBP
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module XRBP
|
2
|
+
module WebClient
|
3
|
+
module Plugins
|
4
|
+
# Plugin to automatically parse and convert webclient results,
|
5
|
+
# before returning.
|
6
|
+
#
|
7
|
+
# @example parse json
|
8
|
+
# connection = WebClient::Connection.new
|
9
|
+
# connection.add_plugin :result_parser
|
10
|
+
#
|
11
|
+
# connection.parse_results do |res|
|
12
|
+
# JSON.parse(res)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# connection.url = "https://data.ripple.com/v2/gateways"
|
16
|
+
# connection.perform
|
17
|
+
class ResultParser < ResultParserBase
|
18
|
+
end
|
19
|
+
|
20
|
+
WebClient.register_plugin :result_parser, ResultParser
|
21
|
+
end # module Plugins
|
22
|
+
end # module WebClient
|
23
|
+
end # module XRBP
|
@@ -2,8 +2,12 @@ require 'websocket'
|
|
2
2
|
|
3
3
|
module XRBP
|
4
4
|
module WebSocket
|
5
|
+
# Managed socket connection lifecycle and read/write operations
|
6
|
+
#
|
7
|
+
# @private
|
5
8
|
class Client
|
6
9
|
include EventEmitter
|
10
|
+
include Terminatable
|
7
11
|
|
8
12
|
attr_reader :url, :options
|
9
13
|
|
@@ -12,18 +16,28 @@ module XRBP
|
|
12
16
|
@options = options
|
13
17
|
|
14
18
|
@handshaked = false
|
15
|
-
@closed =
|
19
|
+
@closed = true
|
20
|
+
@completed = true
|
16
21
|
end
|
17
22
|
|
18
23
|
def connect
|
19
|
-
|
24
|
+
emit_signal :connecting
|
25
|
+
|
20
26
|
@closed = false
|
27
|
+
@completed = false
|
21
28
|
socket.connect
|
22
29
|
handshake!
|
23
|
-
|
30
|
+
|
31
|
+
start_read
|
32
|
+
|
24
33
|
self
|
25
34
|
end
|
26
35
|
|
36
|
+
# Add job to internal thread pool.
|
37
|
+
def add_work(&bl)
|
38
|
+
pool.post &bl
|
39
|
+
end
|
40
|
+
|
27
41
|
###
|
28
42
|
|
29
43
|
def open?
|
@@ -34,33 +48,53 @@ module XRBP
|
|
34
48
|
!!@closed
|
35
49
|
end
|
36
50
|
|
51
|
+
def completed?
|
52
|
+
!!@completed
|
53
|
+
end
|
54
|
+
|
55
|
+
# Allow close to be run via seperate thread so
|
56
|
+
# as not to block caller
|
57
|
+
def async_close(err=nil)
|
58
|
+
Thread.new { close(err) }
|
59
|
+
end
|
60
|
+
|
37
61
|
def close(err=nil)
|
38
62
|
return if closed?
|
39
63
|
|
40
64
|
# XXX set closed true first incase callbacks need to check this
|
41
65
|
@closed = true
|
66
|
+
@handshake = nil
|
67
|
+
@handshaked = false
|
68
|
+
|
69
|
+
terminate!
|
42
70
|
|
43
71
|
send_data nil, :type => :close unless socket.pipe_broken
|
44
|
-
|
72
|
+
emit_signal :close, err
|
45
73
|
|
46
|
-
ensure
|
47
|
-
# Always set closed true
|
48
|
-
@closed = true
|
49
74
|
socket.close if socket
|
50
|
-
@handshake = nil
|
51
|
-
@handshaked = false
|
52
75
|
@socket = nil
|
53
|
-
|
54
|
-
|
76
|
+
|
77
|
+
pool.shutdown
|
78
|
+
pool.wait_for_termination
|
79
|
+
@pool = nil
|
80
|
+
|
81
|
+
@completed = true
|
55
82
|
emit :completed
|
83
|
+
self
|
56
84
|
end
|
57
85
|
|
86
|
+
private
|
87
|
+
|
58
88
|
###
|
59
89
|
|
60
90
|
def socket
|
61
91
|
@socket ||= Socket.new self
|
62
92
|
end
|
63
93
|
|
94
|
+
def pool
|
95
|
+
@pool ||= Concurrent::CachedThreadPool.new
|
96
|
+
end
|
97
|
+
|
64
98
|
###
|
65
99
|
|
66
100
|
def handshake
|
@@ -83,43 +117,70 @@ module XRBP
|
|
83
117
|
|
84
118
|
###
|
85
119
|
|
120
|
+
def data_frame(data, type)
|
121
|
+
::WebSocket::Frame::Outgoing::Client.new(:data => data,
|
122
|
+
:type => type,
|
123
|
+
:version => handshake.version)
|
124
|
+
end
|
125
|
+
|
126
|
+
public
|
127
|
+
|
86
128
|
def send_data(data, opt={:type => :text})
|
87
129
|
return if !handshaked? || closed?
|
88
130
|
|
89
|
-
frame = ::WebSocket::Frame::Outgoing::Client.new(:data => data,
|
90
|
-
:type => opt[:type],
|
91
|
-
:version => handshake.version)
|
92
|
-
|
93
131
|
begin
|
132
|
+
frame = data_frame(data, opt[:type])
|
94
133
|
socket.write_nonblock(frame.to_s)
|
95
134
|
|
96
135
|
rescue Errno::EPIPE, OpenSSL::SSL::SSLError => e
|
97
|
-
|
136
|
+
async_close(e)
|
98
137
|
end
|
99
138
|
end
|
100
139
|
|
101
|
-
|
102
|
-
|
140
|
+
private
|
141
|
+
|
142
|
+
def start_read
|
143
|
+
add_work do
|
103
144
|
frame = ::WebSocket::Frame::Incoming::Client.new
|
104
|
-
|
145
|
+
emit_signal :open
|
105
146
|
|
106
|
-
|
147
|
+
cl = trm = eof = false
|
148
|
+
until (trm = terminate?) || (cl = closed?) do
|
107
149
|
begin
|
108
150
|
socket.read_next(frame)
|
109
151
|
|
110
152
|
if msg = frame.next
|
111
|
-
|
153
|
+
emit_signal :message, msg
|
112
154
|
frame = ::WebSocket::Frame::Incoming::Client.new
|
113
155
|
end
|
114
156
|
|
115
157
|
rescue EOFError => e
|
116
|
-
|
117
|
-
|
158
|
+
emit_signal :error, e
|
159
|
+
eof = e
|
118
160
|
|
119
161
|
rescue => e
|
120
|
-
|
162
|
+
emit_signal :error, e
|
121
163
|
end
|
122
164
|
end
|
165
|
+
|
166
|
+
# ... is this right?:
|
167
|
+
async_close(eof) if !!eof && !cl && !trm
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def emit_signal(*args)
|
172
|
+
# TODO add args to queue, and in add_work task, pull 1 item off queue
|
173
|
+
# & emit it (to enforce signal order)
|
174
|
+
begin
|
175
|
+
add_work do
|
176
|
+
emit *args
|
177
|
+
end
|
178
|
+
|
179
|
+
# XXX: handle race condition where connection is closed
|
180
|
+
# between calling emit_signal and pool.post (handle
|
181
|
+
# error, otherwise a mutex would be needed)
|
182
|
+
rescue Concurrent::RejectedExecutionError => e
|
183
|
+
raise e unless closed?
|
123
184
|
end
|
124
185
|
end
|
125
186
|
end # class Client
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The account_info command retrieves information about an
|
5
|
+
# account, its activity, and its XRP balance.
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/account_info.html
|
4
8
|
class AccountInfo < Command
|
5
9
|
attr_accessor :account, :args
|
6
10
|
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The account_lines method returns information about an
|
5
|
+
# account's trust lines, including balances in all non-XRP
|
6
|
+
# currencies and assets
|
7
|
+
#
|
8
|
+
# https://developers.ripple.com/account_lines.html
|
4
9
|
class AccountLines < Command
|
5
10
|
include Paginated
|
6
11
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The account_objects command returns the raw ledger format for
|
5
|
+
# all objects owned by an account
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/account_objects.html
|
4
8
|
class AccountObjects < Command
|
5
9
|
include Paginated
|
6
10
|
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The account_offers method retrieves a list of offers made
|
5
|
+
# by a given account that are outstanding as of a particular
|
6
|
+
# ledger version.
|
7
|
+
#
|
8
|
+
# https://developers.ripple.com/account_offers.html
|
4
9
|
class AccountOffers < Command
|
5
10
|
include Paginated
|
6
11
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The account_tx method retrieves a list of transactions
|
5
|
+
# that involved the specified account.
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/account_tx.html
|
4
8
|
class AccountTx < Command
|
5
9
|
attr_accessor :account, :args
|
6
10
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The book_offers method retrieves a list of offers, also known as
|
5
|
+
# the order book , between two currencies
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/book_offers.html
|
4
8
|
class BookOffers < Command
|
5
9
|
include Paginated
|
6
10
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The ledger_entry method returns a single ledger object
|
5
|
+
# from the XRP Ledger in its raw format
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/ledger_entry.html
|
4
8
|
class LedgerEntry < Command
|
5
9
|
def initialize(args={})
|
6
10
|
@args = args
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module XRBP
|
2
2
|
module WebSocket
|
3
3
|
module Cmds
|
4
|
+
# The server_info command asks the server for a human-readable version
|
5
|
+
# of various information about the rippled server being queried.
|
6
|
+
#
|
7
|
+
# https://developers.ripple.com/server_info.html
|
4
8
|
class ServerInfo < Command
|
5
9
|
def initialize
|
6
10
|
super({'command' => 'server_info'})
|
@@ -4,6 +4,7 @@ module XRBP
|
|
4
4
|
module WebSocket
|
5
5
|
class Command < Message
|
6
6
|
attr_accessor :id
|
7
|
+
attr_reader :json
|
7
8
|
|
8
9
|
def initialize(data)
|
9
10
|
@@id ||= 0
|
@@ -12,8 +13,18 @@ module XRBP
|
|
12
13
|
json = Hash[data]
|
13
14
|
json['id'] = id
|
14
15
|
|
16
|
+
@json = json
|
17
|
+
|
15
18
|
super(json.to_json)
|
16
19
|
end
|
20
|
+
|
21
|
+
def requesting
|
22
|
+
@json[:command] || @json["command"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def requesting?(tgt)
|
26
|
+
requesting.to_s == tgt.to_s
|
27
|
+
end
|
17
28
|
end # class Command
|
18
29
|
end # module WebSocket
|
19
30
|
end # module XRBP
|
@@ -1,10 +1,21 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../thread_registry'
|
2
2
|
|
3
3
|
module XRBP
|
4
4
|
module WebSocket
|
5
|
+
# Primary websocket interface, use Connection to perform
|
6
|
+
# websocket requests.
|
7
|
+
#
|
8
|
+
# @example retrieve data via a websocket
|
9
|
+
# connection = WebSocket::Connection.new "wss://s1.ripple.com:443"
|
10
|
+
# puts connection.send_data('{"command" : "server_info"}')
|
5
11
|
class Connection
|
6
12
|
include EventEmitter
|
7
13
|
include HasPlugin
|
14
|
+
include ThreadRegistry
|
15
|
+
|
16
|
+
def plugin_namespace
|
17
|
+
WebSocket
|
18
|
+
end
|
8
19
|
|
9
20
|
attr_reader :url
|
10
21
|
attr_accessor :parent
|
@@ -12,35 +23,65 @@ module XRBP
|
|
12
23
|
def initialize(url)
|
13
24
|
@url = url
|
14
25
|
@force_quit = false
|
26
|
+
|
27
|
+
yield self if block_given?
|
15
28
|
end
|
16
29
|
|
17
30
|
###
|
18
31
|
|
32
|
+
# Initiate new client connection
|
19
33
|
def connect
|
20
34
|
client.connect
|
21
35
|
end
|
22
36
|
|
37
|
+
# Return next connection of parent if applicable
|
38
|
+
#
|
39
|
+
# @private
|
23
40
|
def next_connection(prev)
|
24
41
|
return nil unless !!parent
|
25
42
|
parent.next_connection(prev)
|
26
43
|
end
|
27
44
|
|
45
|
+
# Add work to the internal client thread pool
|
46
|
+
#
|
47
|
+
# @private
|
48
|
+
def add_work(&bl)
|
49
|
+
client.add_work &bl
|
50
|
+
end
|
51
|
+
|
52
|
+
# Indicates the connection is initialized
|
28
53
|
def initialized?
|
29
54
|
!!@client
|
30
55
|
end
|
31
56
|
|
57
|
+
# Indicates the connection is open
|
32
58
|
def open?
|
33
59
|
initialized? && client.open?
|
34
60
|
end
|
35
61
|
|
62
|
+
# Indicates the connection is closed
|
63
|
+
# (may not be completed)
|
36
64
|
def closed?
|
37
65
|
!open?
|
38
66
|
end
|
39
67
|
|
68
|
+
# Indicates if connection is completely
|
69
|
+
# closed and cleaned up
|
70
|
+
def completed?
|
71
|
+
client.completed?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Close the connection, blocking until completed
|
40
75
|
def close!
|
41
76
|
client.close if open?
|
42
77
|
end
|
43
78
|
|
79
|
+
# Close in a non-blocking way, and immediately return.
|
80
|
+
def async_close!
|
81
|
+
client.async_close if open?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Send raw data via this connection
|
44
85
|
def send_data(data)
|
45
86
|
client.send_data(data)
|
46
87
|
end
|
@@ -51,27 +92,16 @@ module XRBP
|
|
51
92
|
@force_quit
|
52
93
|
end
|
53
94
|
|
95
|
+
# Immediately terminate the connection and all related operations
|
54
96
|
def force_quit!
|
55
97
|
@force_quit = true
|
56
98
|
wake_all
|
57
|
-
|
58
|
-
|
59
|
-
def thread_registry
|
60
|
-
@thread_registry ||= Concurrent::Array.new
|
61
|
-
end
|
62
|
-
|
63
|
-
def rsleep(t)
|
64
|
-
thread_registry << Thread.current
|
65
|
-
sleep(t)
|
66
|
-
thread_registry.delete(Thread.current)
|
67
|
-
end
|
68
|
-
|
69
|
-
def wake_all
|
70
|
-
thread_registry.each { |th| th.wakeup }
|
99
|
+
# TODO immediate terminate socket connection
|
71
100
|
end
|
72
101
|
|
73
102
|
###
|
74
103
|
|
104
|
+
# Block until connection is open
|
75
105
|
def wait_for_open
|
76
106
|
return unless initialized?
|
77
107
|
|
@@ -80,6 +110,7 @@ module XRBP
|
|
80
110
|
} until force_quit? || open?
|
81
111
|
end
|
82
112
|
|
113
|
+
# Block until connection is closed
|
83
114
|
def wait_for_close
|
84
115
|
return unless initialized?
|
85
116
|
|
@@ -88,6 +119,15 @@ module XRBP
|
|
88
119
|
} while !force_quit? && open?
|
89
120
|
end
|
90
121
|
|
122
|
+
# Block until connection is completed
|
123
|
+
def wait_for_completed
|
124
|
+
return unless initialized?
|
125
|
+
|
126
|
+
state_mutex.synchronize {
|
127
|
+
completed_cv.wait(state_mutex, 0.1)
|
128
|
+
} while !force_quit? && !completed?
|
129
|
+
end
|
130
|
+
|
91
131
|
def state_mutex
|
92
132
|
@state_mutex ||= Mutex.new
|
93
133
|
end
|
@@ -100,8 +140,13 @@ module XRBP
|
|
100
140
|
@close_cv ||= ConditionVariable.new
|
101
141
|
end
|
102
142
|
|
143
|
+
def completed_cv
|
144
|
+
@completed_cv ||= ConditionVariable.new
|
145
|
+
end
|
146
|
+
|
103
147
|
###
|
104
148
|
|
149
|
+
# @private
|
105
150
|
def client
|
106
151
|
@client ||= begin
|
107
152
|
client = Client.new(@url)
|
@@ -109,12 +154,12 @@ module XRBP
|
|
109
154
|
|
110
155
|
client.on :connecting do
|
111
156
|
conn.emit :connecting
|
112
|
-
conn.parent.emit :connecting if conn.parent
|
157
|
+
conn.parent.emit :connecting, conn if conn.parent
|
113
158
|
end
|
114
159
|
|
115
160
|
client.on :open do
|
116
161
|
conn.emit :open
|
117
|
-
conn.parent.emit :open if conn.parent
|
162
|
+
conn.parent.emit :open, conn if conn.parent
|
118
163
|
|
119
164
|
conn.state_mutex.synchronize {
|
120
165
|
conn.open_cv.signal
|
@@ -127,7 +172,7 @@ module XRBP
|
|
127
172
|
|
128
173
|
client.on :close do
|
129
174
|
conn.emit :close
|
130
|
-
conn.parent.emit :close if conn.parent
|
175
|
+
conn.parent.emit :close, conn if conn.parent
|
131
176
|
|
132
177
|
conn.state_mutex.synchronize {
|
133
178
|
conn.close_cv.signal
|
@@ -140,12 +185,20 @@ module XRBP
|
|
140
185
|
|
141
186
|
client.on :completed do |err|
|
142
187
|
conn.emit :completed
|
143
|
-
conn.parent.emit :completed if conn.parent
|
188
|
+
conn.parent.emit :completed, conn if conn.parent
|
189
|
+
|
190
|
+
conn.state_mutex.synchronize {
|
191
|
+
conn.completed_cv.signal
|
192
|
+
}
|
193
|
+
|
194
|
+
conn.plugins.each { |plg|
|
195
|
+
plg.completed if plg.respond_to?(:completed)
|
196
|
+
}
|
144
197
|
end
|
145
198
|
|
146
199
|
client.on :error do |err|
|
147
200
|
conn.emit :error, err
|
148
|
-
conn.parent.emit :error, err if conn.parent
|
201
|
+
conn.parent.emit :error, conn, err if conn.parent
|
149
202
|
|
150
203
|
conn.plugins.each { |plg|
|
151
204
|
plg.error err if plg.respond_to?(:error)
|
@@ -154,7 +207,7 @@ module XRBP
|
|
154
207
|
|
155
208
|
client.on :message do |msg|
|
156
209
|
conn.emit :message, msg
|
157
|
-
conn.parent.emit :message, msg if conn.parent
|
210
|
+
conn.parent.emit :message, conn, msg if conn.parent
|
158
211
|
|
159
212
|
conn.plugins.each { |plg|
|
160
213
|
plg.message msg if plg.respond_to?(:message)
|
@@ -165,5 +218,5 @@ module XRBP
|
|
165
218
|
end
|
166
219
|
end
|
167
220
|
end # class Connection
|
168
|
-
end # module WebSocket
|
221
|
+
end # module WebSocket
|
169
222
|
end # module XRBP
|