xrbp 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|