myxi 1.0.0 → 1.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/lib/myxi.rb +5 -0
- data/lib/myxi/action.rb +8 -1
- data/lib/myxi/default_actions.rb +22 -2
- data/lib/myxi/environment.rb +21 -0
- data/lib/myxi/railtie.rb +8 -0
- data/lib/myxi/server.rb +24 -3
- data/lib/myxi/session.rb +25 -5
- data/lib/myxi/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f04936ddd50485e99372aa1248f99bf41fbc6c61
|
4
|
+
data.tar.gz: 16b9d860964f5f8c733697cc13001977949ca541
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aabc52d678b70c8fc7d929bb00d9b876b5fc8a7c847cc9d7f8be0f3350a21579f7cb309cc88d1b25f9f57dc6f2effe74de9e59278ae97143a7932822ae265f8
|
7
|
+
data.tar.gz: 4e9b22ef5ba86dc807a8f8240a510c40ae2602fde0f47f9cc177e9a1857724b0114ab0fc2e21395d87c6595b483718dca8bd9a2e05b90924198f58f7ab63b5d7
|
data/lib/myxi.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'myxi/exchange'
|
2
|
+
require 'myxi/railtie' if defined?(Rails)
|
3
|
+
|
1
4
|
module Myxi
|
2
5
|
class << self
|
3
6
|
|
7
|
+
class Error < StandardError; end
|
8
|
+
|
4
9
|
#
|
5
10
|
# Return a bunny client instance which will be used by the web socket service.
|
6
11
|
# This can be overriden if you already have a connection RabbitMQ available
|
data/lib/myxi/action.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'myxi/environment'
|
2
|
+
|
1
3
|
module Myxi
|
2
4
|
class Action
|
3
5
|
|
@@ -13,7 +15,12 @@ module Myxi
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def execute(session, payload = {})
|
16
|
-
|
18
|
+
environment = Environment.new(session, payload)
|
19
|
+
environment.instance_exec(session, payload, &@block)
|
20
|
+
rescue Environment::Error => e
|
21
|
+
session.send('Error', :error => e.class.to_s.split('::').last)
|
22
|
+
rescue => e
|
23
|
+
session.send('InternalError', :error => e.class.to_s, :message => e.message)
|
17
24
|
end
|
18
25
|
|
19
26
|
end
|
data/lib/myxi/default_actions.rb
CHANGED
@@ -1,13 +1,33 @@
|
|
1
1
|
Myxi::Action.add(:Subscribe) do |session, payload|
|
2
|
-
|
2
|
+
if payload['routing_keys'].is_a?(Array)
|
3
|
+
for key in payload['routing_keys']
|
4
|
+
session.subscribe(payload['exchange'], key)
|
5
|
+
end
|
6
|
+
else
|
7
|
+
session.subscribe(payload['exchange'], payload['routing_key'])
|
8
|
+
end
|
3
9
|
end
|
4
10
|
|
5
11
|
Myxi::Action.add(:Unsubscribe) do |session, payload|
|
6
12
|
if payload['exchange'] && payload['routing_key']
|
7
|
-
|
13
|
+
if payload['routing_keys'].is_a?(Array)
|
14
|
+
for key in payload['routing_keys']
|
15
|
+
session.unsubscribe(payload['exchange'], key)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
session.unsubscribe(payload['exchange'], payload['routing_key'])
|
19
|
+
end
|
8
20
|
elsif payload['exchange'] && payload['routing_key'].nil?
|
9
21
|
session.unsubscribe_all_for_exchange(payload['exchange'])
|
10
22
|
else
|
11
23
|
session.unsubscribe_all
|
12
24
|
end
|
13
25
|
end
|
26
|
+
|
27
|
+
Myxi::Action.add(:ListSubscriptions) do |session, payload|
|
28
|
+
session.send "YourSubscriptions", :subscriptions => session.subscriptions
|
29
|
+
end
|
30
|
+
|
31
|
+
Myxi::Action.add(:Ping) do |session, payload|
|
32
|
+
session.send "Pong", :time => Time.now.to_i
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Myxi
|
2
|
+
class Environment
|
3
|
+
|
4
|
+
class Error < StandardError; end
|
5
|
+
class AuthRequired < Error; end
|
6
|
+
|
7
|
+
def initialize(session, payload = {})
|
8
|
+
@session, @payload = session, payload
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :session
|
12
|
+
attr_reader :payload
|
13
|
+
|
14
|
+
def auth_required!
|
15
|
+
if session.auth_object.nil?
|
16
|
+
raise AuthRequired, "Authentication is required for this action"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/myxi/railtie.rb
ADDED
data/lib/myxi/server.rb
CHANGED
@@ -19,14 +19,30 @@ module Myxi
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def sessions
|
23
|
+
@sessions ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
def monitor_sessions
|
27
|
+
unless options[:touch_interval] == 0
|
28
|
+
Thread.new do
|
29
|
+
loop do
|
30
|
+
sessions.each(&:touch)
|
31
|
+
sleep options[:touch_interval] || 60
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
22
37
|
def run
|
23
38
|
Myxi::Exchange.declare_all
|
24
39
|
port = (options[:port] || ENV['MYXI_PORT'] || ENV['PORT'] || 5005).to_i
|
25
40
|
puts "Running Myxi Web Socket Server on 0.0.0.0:#{port}"
|
41
|
+
monitor_sessions
|
26
42
|
EM.run do
|
27
43
|
EM::WebSocket.run(:host => options[:bind_address] || ENV['MYXI_BIND_ADDRESS'] || '0.0.0.0', :port => port) do |ws|
|
28
44
|
|
29
|
-
session = Session.new(ws)
|
45
|
+
sessions << session = Session.new(self, ws)
|
30
46
|
|
31
47
|
ws.onopen do |handshake|
|
32
48
|
case handshake.path
|
@@ -36,7 +52,10 @@ module Myxi
|
|
36
52
|
|
37
53
|
session.queue = Myxi.channel.queue("", :exclusive => true)
|
38
54
|
session.queue.subscribe do |delivery_info, properties, body|
|
39
|
-
|
55
|
+
if hash = JSON.parse(body) rescue nil
|
56
|
+
hash['mq'] = {'e' => delivery_info.exchange, 'rk' => delivery_info.routing_key}
|
57
|
+
ws.send(hash.to_json.force_encoding('UTF-8'))
|
58
|
+
end
|
40
59
|
end
|
41
60
|
else
|
42
61
|
log "[#{session.id}] Invalid path"
|
@@ -48,11 +67,13 @@ module Myxi
|
|
48
67
|
ws.onclose do
|
49
68
|
log "[#{session.id}] Disconnected"
|
50
69
|
session.queue.delete if session.queue
|
70
|
+
sessions.delete(session)
|
51
71
|
end
|
52
72
|
|
53
73
|
ws.onmessage do |msg|
|
54
74
|
if ws.state == :connected
|
55
|
-
|
75
|
+
json = JSON.parse(msg) rescue nil
|
76
|
+
if json.is_a?(Hash)
|
56
77
|
session.tag = json['tag'] || nil
|
57
78
|
payload = json['payload'] || {}
|
58
79
|
if action = Myxi::Action::ACTIONS[json['action'].to_sym]
|
data/lib/myxi/session.rb
CHANGED
@@ -4,12 +4,14 @@ require 'myxi/exchange'
|
|
4
4
|
module Myxi
|
5
5
|
class Session
|
6
6
|
|
7
|
-
def initialize(ws)
|
7
|
+
def initialize(server, ws)
|
8
|
+
@server = server
|
8
9
|
@ws = ws
|
9
10
|
@id = SecureRandom.hex(8)
|
10
11
|
end
|
11
12
|
|
12
13
|
attr_reader :id
|
14
|
+
attr_reader :server
|
13
15
|
attr_reader :ws
|
14
16
|
attr_accessor :queue
|
15
17
|
attr_accessor :auth_object
|
@@ -26,7 +28,7 @@ module Myxi
|
|
26
28
|
# Send an event back to the client on this session
|
27
29
|
#
|
28
30
|
def send(name, payload = {})
|
29
|
-
ws.send({:event => name, :tag => tag, :payload => payload}.to_json)
|
31
|
+
ws.send({:event => name, :tag => tag, :payload => payload}.to_json.force_encoding('UTF-8'))
|
30
32
|
end
|
31
33
|
|
32
34
|
#
|
@@ -38,7 +40,7 @@ module Myxi
|
|
38
40
|
queue.bind(exchange.exchange_name.to_s, :routing_key => routing_key.to_s)
|
39
41
|
subscriptions[exchange_name.to_s] ||= []
|
40
42
|
subscriptions[exchange_name.to_s] << routing_key.to_s
|
41
|
-
|
43
|
+
server.log "[#{id}] Subscribed to #{exchange_name} / #{routing_key}"
|
42
44
|
send('Subscribed', :exchange => exchange_name, :routing_key => routing_key)
|
43
45
|
else
|
44
46
|
send('Error', :error => 'SubscriptionDenied', :exchange => exchange_name, :routing_key => routing_key)
|
@@ -51,12 +53,13 @@ module Myxi
|
|
51
53
|
#
|
52
54
|
# Unsubscribe this session from the given exchange name and routing key
|
53
55
|
#
|
54
|
-
def unsubscribe(exchange_name, routing_key)
|
56
|
+
def unsubscribe(exchange_name, routing_key, auto = false)
|
55
57
|
queue.unbind(exchange_name.to_s, :routing_key => routing_key.to_s)
|
56
58
|
if subscriptions[exchange_name.to_s]
|
57
59
|
subscriptions[exchange_name.to_s].delete(routing_key.to_s)
|
58
60
|
end
|
59
|
-
|
61
|
+
server.log "[#{id}] Unsubscribed from #{exchange_name}/#{routing_key}"
|
62
|
+
send('Unsubscribed', :exchange_name => exchange_name, :routing_key => routing_key, :auto => auto)
|
60
63
|
end
|
61
64
|
|
62
65
|
#
|
@@ -79,5 +82,22 @@ module Myxi
|
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
85
|
+
#
|
86
|
+
# Called by the server every so often whenever this session is active. This
|
87
|
+
# should verify that subscriptions are still valid etc...
|
88
|
+
#
|
89
|
+
def touch
|
90
|
+
subscriptions.each do |exchange_name, routing_keys|
|
91
|
+
if exchange = Myxi::Exchange::EXCHANGES[exchange_name.to_sym]
|
92
|
+
routing_keys.each do |routing_key|
|
93
|
+
unless exchange.can_subscribe?(routing_key, self.auth_object)
|
94
|
+
puts "[#{id}] Session is not longer allowed to subscibe to #{exchange_name}/#{routing_key}"
|
95
|
+
unsubscribe(exchange_name, routing_key, true)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
82
102
|
end
|
83
103
|
end
|
data/lib/myxi/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: myxi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Cooke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -60,7 +60,9 @@ files:
|
|
60
60
|
- lib/myxi.rb
|
61
61
|
- lib/myxi/action.rb
|
62
62
|
- lib/myxi/default_actions.rb
|
63
|
+
- lib/myxi/environment.rb
|
63
64
|
- lib/myxi/exchange.rb
|
65
|
+
- lib/myxi/railtie.rb
|
64
66
|
- lib/myxi/server.rb
|
65
67
|
- lib/myxi/session.rb
|
66
68
|
- lib/myxi/version.rb
|
@@ -89,3 +91,4 @@ signing_key:
|
|
89
91
|
specification_version: 4
|
90
92
|
summary: A RabbitMQ-based web socket server & framework
|
91
93
|
test_files: []
|
94
|
+
has_rdoc:
|