peatio 0.6.3 → 2.4.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +148 -8
- data/Gemfile +3 -1
- data/Gemfile.lock +42 -30
- data/lib/peatio.rb +15 -2
- data/lib/peatio/command/inject.rb +3 -1
- data/lib/peatio/command/root.rb +0 -2
- data/lib/peatio/command/security.rb +2 -3
- data/lib/peatio/command/service.rb +18 -4
- data/lib/peatio/injectors/peatio_events.rb +117 -53
- data/lib/peatio/logger.rb +9 -7
- data/lib/peatio/metrics/server.rb +15 -0
- data/lib/peatio/mq/client.rb +35 -14
- data/lib/peatio/ranger/connection.rb +110 -0
- data/lib/peatio/ranger/events.rb +11 -0
- data/lib/peatio/ranger/router.rb +234 -0
- data/lib/peatio/ranger/web_socket.rb +68 -0
- data/lib/peatio/version.rb +1 -1
- data/peatio.gemspec +21 -17
- metadata +76 -32
- data/lib/peatio/command/amqp.rb +0 -9
- data/lib/peatio/mq/events.rb +0 -128
- data/lib/peatio/ranger.rb +0 -135
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Peatio::Ranger
|
4
|
+
def self.run(jwt_public_key, exchange_name, opts={})
|
5
|
+
host = opts[:ranger_host] || ENV["RANGER_HOST"] || "0.0.0.0"
|
6
|
+
port = opts[:ranger_port] || ENV["RANGER_PORT"] || "8081"
|
7
|
+
|
8
|
+
authenticator = Peatio::Auth::JWTAuthenticator.new(jwt_public_key)
|
9
|
+
|
10
|
+
logger = Peatio::Logger.logger
|
11
|
+
logger.info "Starting the server on port #{port}"
|
12
|
+
|
13
|
+
client = Peatio::MQ::Client.new
|
14
|
+
router = Peatio::Ranger::Router.new(opts[:registry])
|
15
|
+
client.subscribe(exchange_name, &router.method(:on_message))
|
16
|
+
|
17
|
+
if opts[:display_stats]
|
18
|
+
EM.add_periodic_timer(opts[:stats_period]) do
|
19
|
+
Peatio::Logger.logger.info { router.stats }
|
20
|
+
Peatio::Logger.logger.debug { router.debug }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
EM::WebSocket.start(host: host, port: port, secure: false) do |socket|
|
25
|
+
connection = Peatio::Ranger::Connection.new(router, socket, logger)
|
26
|
+
socket.onopen do |hs|
|
27
|
+
connection.handshake(authenticator, hs)
|
28
|
+
router.on_connection_open(connection)
|
29
|
+
end
|
30
|
+
|
31
|
+
socket.onmessage do |msg|
|
32
|
+
connection.handle(msg)
|
33
|
+
end
|
34
|
+
|
35
|
+
socket.onping do |value|
|
36
|
+
logger.debug { "Received ping: #{value}" }
|
37
|
+
end
|
38
|
+
|
39
|
+
socket.onclose do
|
40
|
+
logger.debug { "Websocket connection closed" }
|
41
|
+
router.on_connection_close(connection)
|
42
|
+
end
|
43
|
+
|
44
|
+
socket.onerror do |e|
|
45
|
+
logger.info { "WebSocket Error: #{e.message}" }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.run!(jwt_public_key, exchange_name, opts={})
|
51
|
+
metrics_host = opts[:metrics_host] || ENV["METRICS_HOST"] || "0.0.0.0"
|
52
|
+
metrics_port = opts[:metrics_port] || ENV["METRICS_PORT"] || "8082"
|
53
|
+
|
54
|
+
EM.run do
|
55
|
+
run(jwt_public_key, exchange_name, opts)
|
56
|
+
|
57
|
+
if opts[:registry]
|
58
|
+
thin = Rack::Handler.get("thin")
|
59
|
+
thin.run(Peatio::Metrics::Server.app(opts[:registry]), Host: metrics_host, Port: metrics_port)
|
60
|
+
end
|
61
|
+
|
62
|
+
trap("INT") do
|
63
|
+
puts "\nSIGINT received, stopping ranger..."
|
64
|
+
EM.stop
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/peatio/version.rb
CHANGED
data/peatio.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path("
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require "peatio/version"
|
5
6
|
|
@@ -9,38 +10,41 @@ Gem::Specification.new do |spec|
|
|
9
10
|
spec.authors = ["Louis B.", "Camille M."]
|
10
11
|
spec.email = ["lbellet@heliostech.fr"]
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
13
|
+
spec.summary = "Peatio is a gem for running critical core services"
|
14
|
+
spec.description = "Peatio gem contains microservices and command line tools"
|
14
15
|
spec.homepage = "https://www.peatio.tech"
|
15
16
|
|
16
17
|
# Specify which files should be added to the gem when it is released.
|
17
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
-
spec.files = Dir.chdir(File.expand_path(
|
19
|
-
`git ls-files -z`.split("\x0").reject {
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test|spec|features)/}) }
|
20
21
|
end
|
21
22
|
spec.bindir = "bin"
|
22
|
-
spec.executables = spec.files.grep(%r{^bin/}) {
|
23
|
+
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
23
24
|
spec.require_paths = ["lib"]
|
24
25
|
|
25
26
|
spec.add_dependency "activemodel", "> 5.2", "<= 6.0.0"
|
26
|
-
spec.add_dependency "clamp"
|
27
27
|
spec.add_dependency "amqp"
|
28
|
-
spec.add_dependency "
|
28
|
+
spec.add_dependency "bunny"
|
29
|
+
spec.add_dependency "clamp"
|
29
30
|
spec.add_dependency "em-websocket"
|
30
|
-
spec.add_dependency "
|
31
|
+
spec.add_dependency "eventmachine"
|
31
32
|
spec.add_dependency "jwt"
|
32
|
-
spec.add_dependency "
|
33
|
+
spec.add_dependency "mysql2"
|
34
|
+
spec.add_dependency "prometheus-client"
|
35
|
+
spec.add_dependency "thin"
|
33
36
|
|
34
|
-
spec.add_development_dependency "bundler", "~> 1.16"
|
35
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
36
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
37
37
|
spec.add_development_dependency "bump"
|
38
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
39
|
+
spec.add_development_dependency "bunny-mock"
|
38
40
|
spec.add_development_dependency "em-spec"
|
39
41
|
spec.add_development_dependency "em-websocket-client"
|
40
|
-
spec.add_development_dependency "
|
41
|
-
spec.add_development_dependency "
|
42
|
-
spec.add_development_dependency "
|
42
|
+
spec.add_development_dependency "irb"
|
43
|
+
spec.add_development_dependency "pry-byebug"
|
44
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
45
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
43
46
|
spec.add_development_dependency "rspec_junit_formatter"
|
44
47
|
spec.add_development_dependency "rubocop-github"
|
45
|
-
spec.add_development_dependency "
|
48
|
+
spec.add_development_dependency "simplecov"
|
49
|
+
spec.add_development_dependency "simplecov-json"
|
46
50
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peatio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.4.0.pre.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis B.
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 6.0.0
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
35
|
+
name: amqp
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
49
|
+
name: bunny
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
@@ -60,7 +60,7 @@ dependencies:
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: clamp
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
@@ -88,7 +88,7 @@ dependencies:
|
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
|
-
name:
|
91
|
+
name: eventmachine
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
@@ -116,7 +116,7 @@ dependencies:
|
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
- !ruby/object:Gem::Dependency
|
119
|
-
name:
|
119
|
+
name: mysql2
|
120
120
|
requirement: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
@@ -130,49 +130,63 @@ dependencies:
|
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
- !ruby/object:Gem::Dependency
|
133
|
-
name:
|
133
|
+
name: prometheus-client
|
134
134
|
requirement: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
139
|
-
type: :
|
138
|
+
version: '0'
|
139
|
+
type: :runtime
|
140
140
|
prerelease: false
|
141
141
|
version_requirements: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
145
|
+
version: '0'
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
|
-
name:
|
147
|
+
name: thin
|
148
148
|
requirement: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '0'
|
153
|
+
type: :runtime
|
154
|
+
prerelease: false
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
- !ruby/object:Gem::Dependency
|
161
|
+
name: bump
|
162
|
+
requirement: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
type: :development
|
154
168
|
prerelease: false
|
155
169
|
version_requirements: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
|
-
- - "
|
171
|
+
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
173
|
+
version: '0'
|
160
174
|
- !ruby/object:Gem::Dependency
|
161
|
-
name:
|
175
|
+
name: bundler
|
162
176
|
requirement: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
180
|
+
version: '1.16'
|
167
181
|
type: :development
|
168
182
|
prerelease: false
|
169
183
|
version_requirements: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
187
|
+
version: '1.16'
|
174
188
|
- !ruby/object:Gem::Dependency
|
175
|
-
name:
|
189
|
+
name: bunny-mock
|
176
190
|
requirement: !ruby/object:Gem::Requirement
|
177
191
|
requirements:
|
178
192
|
- - ">="
|
@@ -214,7 +228,7 @@ dependencies:
|
|
214
228
|
- !ruby/object:Gem::Version
|
215
229
|
version: '0'
|
216
230
|
- !ruby/object:Gem::Dependency
|
217
|
-
name:
|
231
|
+
name: irb
|
218
232
|
requirement: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
234
|
- - ">="
|
@@ -228,7 +242,7 @@ dependencies:
|
|
228
242
|
- !ruby/object:Gem::Version
|
229
243
|
version: '0'
|
230
244
|
- !ruby/object:Gem::Dependency
|
231
|
-
name:
|
245
|
+
name: pry-byebug
|
232
246
|
requirement: !ruby/object:Gem::Requirement
|
233
247
|
requirements:
|
234
248
|
- - ">="
|
@@ -242,7 +256,35 @@ dependencies:
|
|
242
256
|
- !ruby/object:Gem::Version
|
243
257
|
version: '0'
|
244
258
|
- !ruby/object:Gem::Dependency
|
245
|
-
name:
|
259
|
+
name: rake
|
260
|
+
requirement: !ruby/object:Gem::Requirement
|
261
|
+
requirements:
|
262
|
+
- - "~>"
|
263
|
+
- !ruby/object:Gem::Version
|
264
|
+
version: '10.0'
|
265
|
+
type: :development
|
266
|
+
prerelease: false
|
267
|
+
version_requirements: !ruby/object:Gem::Requirement
|
268
|
+
requirements:
|
269
|
+
- - "~>"
|
270
|
+
- !ruby/object:Gem::Version
|
271
|
+
version: '10.0'
|
272
|
+
- !ruby/object:Gem::Dependency
|
273
|
+
name: rspec
|
274
|
+
requirement: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - "~>"
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '3.0'
|
279
|
+
type: :development
|
280
|
+
prerelease: false
|
281
|
+
version_requirements: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - "~>"
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '3.0'
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: rspec_junit_formatter
|
246
288
|
requirement: !ruby/object:Gem::Requirement
|
247
289
|
requirements:
|
248
290
|
- - ">="
|
@@ -256,7 +298,7 @@ dependencies:
|
|
256
298
|
- !ruby/object:Gem::Version
|
257
299
|
version: '0'
|
258
300
|
- !ruby/object:Gem::Dependency
|
259
|
-
name:
|
301
|
+
name: rubocop-github
|
260
302
|
requirement: !ruby/object:Gem::Requirement
|
261
303
|
requirements:
|
262
304
|
- - ">="
|
@@ -270,7 +312,7 @@ dependencies:
|
|
270
312
|
- !ruby/object:Gem::Version
|
271
313
|
version: '0'
|
272
314
|
- !ruby/object:Gem::Dependency
|
273
|
-
name:
|
315
|
+
name: simplecov
|
274
316
|
requirement: !ruby/object:Gem::Requirement
|
275
317
|
requirements:
|
276
318
|
- - ">="
|
@@ -284,7 +326,7 @@ dependencies:
|
|
284
326
|
- !ruby/object:Gem::Version
|
285
327
|
version: '0'
|
286
328
|
- !ruby/object:Gem::Dependency
|
287
|
-
name:
|
329
|
+
name: simplecov-json
|
288
330
|
requirement: !ruby/object:Gem::Requirement
|
289
331
|
requirements:
|
290
332
|
- - ">="
|
@@ -327,7 +369,6 @@ files:
|
|
327
369
|
- lib/peatio/blockchain/abstract.rb
|
328
370
|
- lib/peatio/blockchain/error.rb
|
329
371
|
- lib/peatio/blockchain/registry.rb
|
330
|
-
- lib/peatio/command/amqp.rb
|
331
372
|
- lib/peatio/command/base.rb
|
332
373
|
- lib/peatio/command/db.rb
|
333
374
|
- lib/peatio/command/inject.rb
|
@@ -338,9 +379,12 @@ files:
|
|
338
379
|
- lib/peatio/executor.rb
|
339
380
|
- lib/peatio/injectors/peatio_events.rb
|
340
381
|
- lib/peatio/logger.rb
|
382
|
+
- lib/peatio/metrics/server.rb
|
341
383
|
- lib/peatio/mq/client.rb
|
342
|
-
- lib/peatio/
|
343
|
-
- lib/peatio/ranger.rb
|
384
|
+
- lib/peatio/ranger/connection.rb
|
385
|
+
- lib/peatio/ranger/events.rb
|
386
|
+
- lib/peatio/ranger/router.rb
|
387
|
+
- lib/peatio/ranger/web_socket.rb
|
344
388
|
- lib/peatio/security/key_generator.rb
|
345
389
|
- lib/peatio/sql/client.rb
|
346
390
|
- lib/peatio/sql/schema.rb
|
@@ -364,9 +408,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
364
408
|
version: '0'
|
365
409
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
366
410
|
requirements:
|
367
|
-
- - "
|
411
|
+
- - ">"
|
368
412
|
- !ruby/object:Gem::Version
|
369
|
-
version:
|
413
|
+
version: 1.3.1
|
370
414
|
requirements: []
|
371
415
|
rubygems_version: 3.0.3
|
372
416
|
signing_key:
|
data/lib/peatio/command/amqp.rb
DELETED
data/lib/peatio/mq/events.rb
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
require "socket"
|
2
|
-
|
3
|
-
module Peatio::MQ::Events
|
4
|
-
def self.subscribe!
|
5
|
-
ranger = RangerEvents.new
|
6
|
-
ranger.subscribe
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.publish(type, id, event, payload)
|
10
|
-
@@client ||= begin
|
11
|
-
ranger = RangerEvents.new
|
12
|
-
ranger.connect!
|
13
|
-
ranger
|
14
|
-
end
|
15
|
-
|
16
|
-
@@client.publish(type, id, event, payload) do
|
17
|
-
yield if block_given?
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Client
|
22
|
-
attr_accessor :streams, :authorized, :user
|
23
|
-
|
24
|
-
@@all = []
|
25
|
-
|
26
|
-
def self.all
|
27
|
-
@@all
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.user(user)
|
31
|
-
@@all.each do |handler|
|
32
|
-
if handler.user == user
|
33
|
-
yield handler
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def initialize(socket, streams = {})
|
39
|
-
@socket = socket
|
40
|
-
@streams = streams
|
41
|
-
|
42
|
-
@user = ""
|
43
|
-
@authorized = false
|
44
|
-
|
45
|
-
@@all << self
|
46
|
-
end
|
47
|
-
|
48
|
-
def send_payload(message)
|
49
|
-
@socket.send message.to_json
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class RangerEvents
|
54
|
-
attr_accessor :exchange_name
|
55
|
-
|
56
|
-
def initialize
|
57
|
-
@exchange_name = "peatio.events.ranger"
|
58
|
-
end
|
59
|
-
|
60
|
-
def connect!
|
61
|
-
if Peatio::MQ::Client.channel.nil?
|
62
|
-
Peatio::MQ::Client.new
|
63
|
-
Peatio::MQ::Client.connect!
|
64
|
-
Peatio::MQ::Client.create_channel!
|
65
|
-
end
|
66
|
-
@exchange = Peatio::MQ::Client.channel.topic(@exchange_name)
|
67
|
-
end
|
68
|
-
|
69
|
-
def publish(type, id, event, payload)
|
70
|
-
routing_key = [type, id, event].join(".")
|
71
|
-
serialized_data = JSON.dump(payload)
|
72
|
-
|
73
|
-
@exchange.publish(serialized_data, routing_key: routing_key)
|
74
|
-
|
75
|
-
Peatio::Logger::debug { "published event to #{routing_key} " }
|
76
|
-
|
77
|
-
yield if block_given?
|
78
|
-
end
|
79
|
-
|
80
|
-
def subscribe
|
81
|
-
exchange = Peatio::MQ::Client.channel.topic(@exchange_name)
|
82
|
-
|
83
|
-
suffix = "#{Socket.gethostname.split(/-/).last}#{Random.rand(10_000)}"
|
84
|
-
|
85
|
-
queue_name = "#{@topic_name}.ranger.#{suffix}"
|
86
|
-
|
87
|
-
Peatio::MQ::Client.channel
|
88
|
-
.queue(queue_name, durable: false, auto_delete: true)
|
89
|
-
.bind(exchange, routing_key: "#").subscribe do |delivery_info, metadata, payload|
|
90
|
-
|
91
|
-
# type@id@event
|
92
|
-
# type can be public|private
|
93
|
-
# id can be user id or market
|
94
|
-
# event can be anything like order_completed or just trade
|
95
|
-
|
96
|
-
routing_key = delivery_info.routing_key
|
97
|
-
if routing_key.count(".") != 2
|
98
|
-
Peatio::Logger::error do
|
99
|
-
"got invalid routing key from amqp: #{routing_key}"
|
100
|
-
end
|
101
|
-
|
102
|
-
next
|
103
|
-
end
|
104
|
-
|
105
|
-
type, id, event = routing_key.split(".")
|
106
|
-
payload_decoded = JSON.parse payload
|
107
|
-
|
108
|
-
if type == "private"
|
109
|
-
Client.user(id) do |client|
|
110
|
-
if client.streams.include?(event)
|
111
|
-
client.send_payload(event => payload_decoded)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
next
|
116
|
-
end
|
117
|
-
|
118
|
-
stream = [id, event].join(".")
|
119
|
-
|
120
|
-
Client.all.each do |handler|
|
121
|
-
if handler.streams.include?(id) or handler.streams.include?(stream)
|
122
|
-
handler.send_payload(stream => payload_decoded)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|