power_strip 0.1.2 → 0.2.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/power_strip.rb +7 -1
- data/lib/power_strip/app.rb +41 -34
- data/lib/power_strip/channel.rb +9 -1
- data/lib/power_strip/channel_list.rb +9 -1
- data/lib/power_strip/connection.rb +22 -0
- data/lib/power_strip/version.rb +1 -1
- data/opal/power_strip.rb +67 -34
- data/power_strip.gemspec +3 -0
- metadata +46 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c9e3d8262f810ab4fb28ccf752acbfafcaa6628
|
4
|
+
data.tar.gz: fcfa3d47d3739d813a03ae51664bd6efa68be337
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f2e2aff4dbc161af1a06d9e1f26284e6202ccb238c4ac9e4870ef437a2b09cb69ac6a617a2e5945b0571de26e9e86c69ffad212c2c7fbdf72aaac2cd8d9ef2b
|
7
|
+
data.tar.gz: fff40297418a13a67dc4d0ecbe7fd2b8f30d7aa2a91306c04c6d570a45c08d3fe1a414b54f6846bf184e2e7504f206b8017e6adb21aaed0c03b6394c87c55306
|
data/lib/power_strip.rb
CHANGED
@@ -30,12 +30,18 @@ module PowerStrip
|
|
30
30
|
def on event_name, channel:, &block
|
31
31
|
app.on event_name, channel: channel, &block
|
32
32
|
end
|
33
|
+
|
34
|
+
class Channel
|
35
|
+
def on message, &block
|
36
|
+
PowerStrip.on(message, channel: name, &block)
|
37
|
+
end
|
38
|
+
end
|
33
39
|
end
|
34
40
|
|
35
41
|
begin
|
36
42
|
require 'opal'
|
37
43
|
Opal.append_path File.expand_path('../../opal', __FILE__)
|
38
|
-
rescue
|
44
|
+
rescue LoadError
|
39
45
|
require 'sprockets'
|
40
46
|
Sprockets.append_path File.expand_path('../js', __FILE__)
|
41
47
|
end
|
data/lib/power_strip/app.rb
CHANGED
@@ -5,6 +5,7 @@ require 'json'
|
|
5
5
|
|
6
6
|
require 'power_strip/channel_list'
|
7
7
|
require 'power_strip/message'
|
8
|
+
require 'power_strip/connection'
|
8
9
|
|
9
10
|
module PowerStrip
|
10
11
|
class App
|
@@ -22,8 +23,10 @@ module PowerStrip
|
|
22
23
|
handlers[event] = []
|
23
24
|
end
|
24
25
|
end
|
26
|
+
@connections = {}
|
25
27
|
end
|
26
28
|
|
29
|
+
# omg I'm so sorry this method looks like this.
|
27
30
|
def call env
|
28
31
|
if Faye::WebSocket.websocket? env
|
29
32
|
socket = Faye::WebSocket.new(env)
|
@@ -31,46 +34,50 @@ module PowerStrip
|
|
31
34
|
subscriptions = Set.new
|
32
35
|
|
33
36
|
socket.on :message do |event|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
rescue => e
|
64
|
-
warn "[PowerStrip] #{e.inspect}"
|
37
|
+
begin
|
38
|
+
message = Message.new(JSON.parse(event.data))
|
39
|
+
channel_name = message.channel
|
40
|
+
channel = channels[channel_name]
|
41
|
+
|
42
|
+
case message.event
|
43
|
+
when '@subscribe'
|
44
|
+
channel << socket
|
45
|
+
subscriptions << channel
|
46
|
+
|
47
|
+
socket.send({
|
48
|
+
event: :subscribed,
|
49
|
+
channel: channel_name,
|
50
|
+
}.to_json)
|
51
|
+
when '@unsubscribe'
|
52
|
+
subscriptions.delete channel
|
53
|
+
channel.delete socket
|
54
|
+
|
55
|
+
socket.send({
|
56
|
+
event: :unsubscribed,
|
57
|
+
channel: channel_name,
|
58
|
+
}.to_json)
|
59
|
+
else
|
60
|
+
@handlers[channel_name][message.event].each do |callback|
|
61
|
+
begin
|
62
|
+
callback[message, @connections[socket]]
|
63
|
+
rescue => e
|
64
|
+
warn "[PowerStrip] #{e.inspect}"
|
65
|
+
end
|
65
66
|
end
|
66
67
|
end
|
68
|
+
rescue JSON::ParserError
|
69
|
+
# Ignore invalid JSON
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
73
|
+
socket.on :open do
|
74
|
+
@connections[socket] = Connection.new(socket)
|
75
|
+
end
|
76
|
+
|
70
77
|
socket.on :close do
|
71
|
-
|
72
|
-
|
73
|
-
|
78
|
+
# Remove this connection from all channels it was subscribed to.
|
79
|
+
subscriptions.each { |channel| channel.delete socket }
|
80
|
+
@connections.delete socket
|
74
81
|
end
|
75
82
|
|
76
83
|
socket.rack_response
|
data/lib/power_strip/channel.rb
CHANGED
@@ -6,8 +6,9 @@ module PowerStrip
|
|
6
6
|
class Channel
|
7
7
|
attr_reader :name, :sockets
|
8
8
|
|
9
|
-
def initialize(name, redis:)
|
9
|
+
def initialize(name, channel_list: {}, redis:)
|
10
10
|
@name = name
|
11
|
+
@channel_list = channel_list
|
11
12
|
@redis = redis
|
12
13
|
@sockets = Set.new
|
13
14
|
end
|
@@ -18,6 +19,13 @@ module PowerStrip
|
|
18
19
|
|
19
20
|
def delete socket
|
20
21
|
@sockets.delete socket
|
22
|
+
|
23
|
+
# Tell the channel list to GC this channel
|
24
|
+
@channel_list.delete @name if empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def empty?
|
28
|
+
@sockets.empty?
|
21
29
|
end
|
22
30
|
|
23
31
|
def send event, message
|
@@ -5,7 +5,11 @@ module PowerStrip
|
|
5
5
|
def initialize(redis:)
|
6
6
|
@redis = redis
|
7
7
|
@channels = Hash.new do |hash, channel|
|
8
|
-
hash[channel.to_s] = Channel.new(
|
8
|
+
hash[channel.to_s] = Channel.new(
|
9
|
+
channel,
|
10
|
+
channel_list: self,
|
11
|
+
redis: redis,
|
12
|
+
)
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
@@ -20,5 +24,9 @@ module PowerStrip
|
|
20
24
|
def delete channel_name
|
21
25
|
@channels.delete channel_name.to_s
|
22
26
|
end
|
27
|
+
|
28
|
+
def has_channel? channel_name
|
29
|
+
@channels.key? channel_name.to_s
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PowerStrip
|
2
|
+
class Connection
|
3
|
+
attr_reader :metadata
|
4
|
+
|
5
|
+
def initialize socket
|
6
|
+
@socket = socket
|
7
|
+
@metadata = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def [] attribute
|
11
|
+
@metadata[attribute]
|
12
|
+
end
|
13
|
+
|
14
|
+
def []= attribute, value
|
15
|
+
@metadata[attribute] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing *args, &block
|
19
|
+
@socket.public_send *args, &block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/power_strip/version.rb
CHANGED
data/opal/power_strip.rb
CHANGED
@@ -9,18 +9,36 @@ module PowerStrip
|
|
9
9
|
@url = url
|
10
10
|
@socket = Bowser.websocket(url)
|
11
11
|
@socket.autoreconnect!
|
12
|
-
@subscriptions =
|
12
|
+
@subscriptions = {}
|
13
13
|
|
14
|
-
@socket.on
|
14
|
+
@socket.on :open do
|
15
|
+
@subscriptions.each { |name, channel| channel.subscribe }
|
16
|
+
end
|
17
|
+
@socket.on :message do |event|
|
18
|
+
message = Message.new(event.data)
|
19
|
+
channel = @subscriptions[message.channel]
|
20
|
+
|
21
|
+
if channel
|
22
|
+
channel.receive_message message
|
23
|
+
end
|
24
|
+
end
|
15
25
|
end
|
16
26
|
|
17
27
|
def subscribe channel_name
|
18
|
-
channel = Channel.new(channel_name,
|
19
|
-
@subscriptions << channel
|
28
|
+
channel = Channel.new(channel_name, self)
|
20
29
|
|
21
|
-
|
22
|
-
|
23
|
-
|
30
|
+
@subscriptions[channel_name] = channel
|
31
|
+
channel.subscribe
|
32
|
+
|
33
|
+
channel
|
34
|
+
end
|
35
|
+
|
36
|
+
def unsubscribe channel_name
|
37
|
+
channel = @subscriptions[channel_name]
|
38
|
+
return if channel.nil?
|
39
|
+
|
40
|
+
@subscriptions.delete channel
|
41
|
+
channel.unsubscribe
|
24
42
|
|
25
43
|
channel
|
26
44
|
end
|
@@ -38,39 +56,18 @@ module PowerStrip
|
|
38
56
|
|
39
57
|
@socket.on native_event, &block
|
40
58
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
Channel = Struct.new(:name, :socket) do
|
44
|
-
def on event_name, &block
|
45
|
-
socket.on :message do |event|
|
46
|
-
message = Message.new(event.data)
|
47
|
-
|
48
|
-
if message.channel == name && message.event == event_name
|
49
|
-
block.call message
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def subscribe
|
55
|
-
socket.send_message(
|
56
|
-
event: :@subscribe,
|
57
|
-
channel: name,
|
58
|
-
)
|
59
|
-
end
|
60
59
|
|
61
|
-
def
|
60
|
+
def send_message channel=nil, event=nil, data=nil
|
62
61
|
promise = Promise.new
|
63
62
|
|
64
|
-
if socket.connected?
|
65
|
-
socket.send_message({
|
66
|
-
|
67
|
-
event: event,
|
68
|
-
data: message,
|
69
|
-
}.select { |k,v| v })
|
63
|
+
if @socket.connected?
|
64
|
+
@socket.send_message({ channel: channel, event: event, data: data }
|
65
|
+
.select { |k,v| v })
|
70
66
|
promise.resolve true
|
71
67
|
else
|
72
68
|
Bowser.window.delay 1 do
|
73
|
-
|
69
|
+
send_message(channel, event, data)
|
70
|
+
.then { promise.resolve true }
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
@@ -80,6 +77,42 @@ module PowerStrip
|
|
80
77
|
end
|
81
78
|
end
|
82
79
|
|
80
|
+
class Channel
|
81
|
+
attr_reader :name, :client
|
82
|
+
|
83
|
+
def initialize name, client
|
84
|
+
@name = name
|
85
|
+
@client = client
|
86
|
+
@handlers = Hash.new { |h, k| h[k] = [] }
|
87
|
+
end
|
88
|
+
|
89
|
+
def on event_name, handler=nil, &block
|
90
|
+
unless handler || block
|
91
|
+
raise ArgumentError, 'PowerStrip::Channel#on requires an event handler'
|
92
|
+
end
|
93
|
+
|
94
|
+
@handlers[event_name] << (handler || block)
|
95
|
+
end
|
96
|
+
|
97
|
+
def receive_message message
|
98
|
+
@handlers[message.event].each do |handler|
|
99
|
+
handler.call message
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def subscribe
|
104
|
+
send :@subscribe, nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def unsubscribe
|
108
|
+
send :@unsubscribe, nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def send event, message=nil
|
112
|
+
client.send_message(name, event, message)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
83
116
|
class Message
|
84
117
|
attr_reader :channel, :event, :data
|
85
118
|
|
data/power_strip.gemspec
CHANGED
@@ -18,6 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_runtime_dependency "faye-websocket", "~> 0.10.4"
|
21
|
+
spec.add_runtime_dependency "grand_central"
|
22
|
+
spec.add_runtime_dependency "redis"
|
23
|
+
spec.add_runtime_dependency "sprockets", "~> 3.6.0"
|
21
24
|
|
22
25
|
spec.add_development_dependency "bundler", "~> 1.12"
|
23
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: power_strip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Gaskins
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faye-websocket
|
@@ -24,6 +24,48 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.10.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: grand_central
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redis
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sprockets
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.6.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.6.0
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: bundler
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +128,7 @@ files:
|
|
86
128
|
- lib/power_strip/app.rb
|
87
129
|
- lib/power_strip/channel.rb
|
88
130
|
- lib/power_strip/channel_list.rb
|
131
|
+
- lib/power_strip/connection.rb
|
89
132
|
- lib/power_strip/message.rb
|
90
133
|
- lib/power_strip/version.rb
|
91
134
|
- opal/power_strip.rb
|
@@ -109,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
152
|
version: '0'
|
110
153
|
requirements: []
|
111
154
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.
|
155
|
+
rubygems_version: 2.6.8
|
113
156
|
signing_key:
|
114
157
|
specification_version: 4
|
115
158
|
summary: Push data from server to client with Ruby
|