slanger 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of slanger might be problematic. Click here for more details.
- data/README.md +3 -1
- data/bin/slanger +5 -1
- data/lib/slanger/channel.rb +20 -1
- data/lib/slanger/redis.rb +1 -1
- data/lib/slanger/webhook.rb +29 -0
- data/slanger.rb +3 -5
- metadata +152 -41
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# Slanger
|
2
|
-
[![Build Status](https://secure.travis-ci.org/stevegraham/slanger.png?branch=master)](http://travis-ci.org/stevegraham/slanger)
|
3
2
|
|
4
3
|
Slanger is an open source server implementation of the Pusher protocol written in Ruby. It is designed to scale horizontally across N nodes and to be agnostic as to which Slanger node a subscriber is connected to, i.e subscribers to the same channel are NOT required to be connected to the same Slanger node. Multiple Slanger nodes can sit behind a load balancer with no special configuration. In essence it was designed to be very easy to scale.
|
5
4
|
|
@@ -101,6 +100,8 @@ Slanger supports several configuration options, which can be supplied as command
|
|
101
100
|
|
102
101
|
-p or --private_key_file Private key file for SSL support. This argument is optional, if given, SSL will be enabled
|
103
102
|
|
103
|
+
-b or --webhook_url URL for webhooks. This argument is optional, if given webhook callbacks will be made http://pusher.com/docs/webhooks
|
104
|
+
|
104
105
|
-c or --cert_chain_file Certificate chain file for SSL support. This argument is optional, if given, SSL will be enabled
|
105
106
|
|
106
107
|
-v or --[no-]verbose This makes Slanger run verbosely, meaning WebSocket frames will be echoed to STDOUT. Useful for debugging
|
@@ -140,3 +141,4 @@ Pusher is an awesome service, very reasonably priced, and run by an awesome crew
|
|
140
141
|
|
141
142
|
© 2011 a Stevie Graham joint.
|
142
143
|
|
144
|
+
|
data/bin/slanger
CHANGED
@@ -45,6 +45,10 @@ OptionParser.new do |opts|
|
|
45
45
|
options[:tls_options][:private_key_file] = p
|
46
46
|
end
|
47
47
|
|
48
|
+
opts.on '-b', '--webhook_url URL', "Callback URL for webhooks" do |p|
|
49
|
+
options[:webhook_url] = p
|
50
|
+
end
|
51
|
+
|
48
52
|
opts.on '-c', '--cert_chain_file FILE', "Certificate chain file for SSL transport" do |p|
|
49
53
|
options[:tls_options] ||= {}
|
50
54
|
options[:tls_options][:cert_chain_file] = p
|
@@ -74,7 +78,7 @@ EM.run do
|
|
74
78
|
Slanger::Config.load options
|
75
79
|
Slanger::Service.run
|
76
80
|
|
77
|
-
puts "\
|
81
|
+
puts "\n"
|
78
82
|
puts "\n"
|
79
83
|
puts " .d8888b. 888 "
|
80
84
|
puts " d88P Y88b 888 "
|
data/lib/slanger/channel.rb
CHANGED
@@ -14,7 +14,7 @@ module Slanger
|
|
14
14
|
include Glamazon::Base
|
15
15
|
extend Forwardable
|
16
16
|
|
17
|
-
def_delegators :channel, :
|
17
|
+
def_delegators :channel, :push
|
18
18
|
|
19
19
|
class << self
|
20
20
|
def from channel_id
|
@@ -40,6 +40,25 @@ module Slanger
|
|
40
40
|
@channel ||= EM::Channel.new
|
41
41
|
end
|
42
42
|
|
43
|
+
def subscribe *a, &blk
|
44
|
+
Slanger::Redis.hincrby('channel_subscriber_count', channel_id, 1).
|
45
|
+
callback do |value|
|
46
|
+
Slanger::Webhook.post name: 'channel_occupied', channel: channel_id if value == 1
|
47
|
+
end
|
48
|
+
|
49
|
+
channel.subscribe *a, &blk
|
50
|
+
end
|
51
|
+
|
52
|
+
def unsubscribe *a, &blk
|
53
|
+
Slanger::Redis.hincrby('channel_subscriber_count', channel_id, -1).
|
54
|
+
callback do |value|
|
55
|
+
Slanger::Webhook.post name: 'channel_vacated', channel: channel_id if value == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
channel.unsubscribe *a, &blk
|
59
|
+
end
|
60
|
+
|
61
|
+
|
43
62
|
# Send a client event to the EventMachine channel.
|
44
63
|
# Only events to channels requiring authentication (private or presence)
|
45
64
|
# are accepted. Public channels only get events from the API.
|
data/lib/slanger/redis.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
require 'em-http-request'
|
3
|
+
|
4
|
+
module Slanger
|
5
|
+
module Webhook
|
6
|
+
def post payload
|
7
|
+
return unless Slanger::Config.webhook_url
|
8
|
+
|
9
|
+
payload = {
|
10
|
+
time_ms: Time.now.strftime('%s%L'), events: [payload]
|
11
|
+
}.to_json
|
12
|
+
|
13
|
+
digest = OpenSSL::Digest::SHA256.new
|
14
|
+
hmac = OpenSSL::HMAC.hexdigest(digest, Slanger::Config.secret, payload)
|
15
|
+
|
16
|
+
Fiber.new do
|
17
|
+
f = Fiber.current
|
18
|
+
|
19
|
+
EM::HttpRequest.new(Slanger::Config.webhook_url).
|
20
|
+
post(body: payload, head: { "X-Pusher-Key" => Slanger::Config.app_key, "X-Pusher-Secret" => hmac }).
|
21
|
+
callback { f.resume }
|
22
|
+
# TODO: Exponentially backed off retries for errors
|
23
|
+
Fiber.yield
|
24
|
+
end.resume
|
25
|
+
end
|
26
|
+
|
27
|
+
extend self
|
28
|
+
end
|
29
|
+
end
|
data/slanger.rb
CHANGED
@@ -11,10 +11,8 @@ module Slanger; end
|
|
11
11
|
EM.epoll
|
12
12
|
EM.kqueue
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
Slanger.autoload File.basename(file, '.rb').classify, file
|
18
|
-
end
|
14
|
+
File.tap do |f|
|
15
|
+
Dir[f.expand_path(f.join(f.dirname(__FILE__),'lib', 'slanger', '*.rb'))].each do |file|
|
16
|
+
Slanger.autoload File.basename(file, '.rb').classify, file
|
19
17
|
end
|
20
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slanger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.12.10
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.12.10
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: em-hiredis
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: 0.1.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.1.0
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: em-websocket
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: 0.3.5
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.3.5
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: rack
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ~>
|
@@ -54,21 +69,31 @@ dependencies:
|
|
54
69
|
version: 1.3.3
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.3.3
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rack-fiber_pool
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
|
-
- - =
|
83
|
+
- - '='
|
64
84
|
- !ruby/object:Gem::Version
|
65
85
|
version: 0.9.1
|
66
86
|
type: :runtime
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - '='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.9.1
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: signature
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ~>
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: 0.1.3
|
77
102
|
type: :runtime
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.1.3
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: activesupport
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ~>
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: 3.1.0
|
88
118
|
type: :runtime
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 3.1.0
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: glamazon
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ~>
|
@@ -98,10 +133,15 @@ dependencies:
|
|
98
133
|
version: 0.3.1
|
99
134
|
type: :runtime
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 0.3.1
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: sinatra
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ~>
|
@@ -109,10 +149,15 @@ dependencies:
|
|
109
149
|
version: 1.2.6
|
110
150
|
type: :runtime
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ~>
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 1.2.6
|
113
158
|
- !ruby/object:Gem::Dependency
|
114
159
|
name: thin
|
115
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
116
161
|
none: false
|
117
162
|
requirements:
|
118
163
|
- - ~>
|
@@ -120,10 +165,15 @@ dependencies:
|
|
120
165
|
version: 1.2.11
|
121
166
|
type: :runtime
|
122
167
|
prerelease: false
|
123
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ~>
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.2.11
|
124
174
|
- !ruby/object:Gem::Dependency
|
125
175
|
name: em-http-request
|
126
|
-
requirement:
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
127
177
|
none: false
|
128
178
|
requirements:
|
129
179
|
- - ~>
|
@@ -131,10 +181,15 @@ dependencies:
|
|
131
181
|
version: 0.3.0
|
132
182
|
type: :runtime
|
133
183
|
prerelease: false
|
134
|
-
version_requirements:
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ~>
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 0.3.0
|
135
190
|
- !ruby/object:Gem::Dependency
|
136
191
|
name: rspec
|
137
|
-
requirement:
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
138
193
|
none: false
|
139
194
|
requirements:
|
140
195
|
- - ~>
|
@@ -142,10 +197,15 @@ dependencies:
|
|
142
197
|
version: 2.6.0
|
143
198
|
type: :development
|
144
199
|
prerelease: false
|
145
|
-
version_requirements:
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ~>
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: 2.6.0
|
146
206
|
- !ruby/object:Gem::Dependency
|
147
207
|
name: pusher
|
148
|
-
requirement:
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
149
209
|
none: false
|
150
210
|
requirements:
|
151
211
|
- - ~>
|
@@ -153,10 +213,15 @@ dependencies:
|
|
153
213
|
version: 0.9.3
|
154
214
|
type: :development
|
155
215
|
prerelease: false
|
156
|
-
version_requirements:
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ~>
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 0.9.3
|
157
222
|
- !ruby/object:Gem::Dependency
|
158
223
|
name: haml
|
159
|
-
requirement:
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
160
225
|
none: false
|
161
226
|
requirements:
|
162
227
|
- - ~>
|
@@ -164,10 +229,15 @@ dependencies:
|
|
164
229
|
version: 3.1.2
|
165
230
|
type: :development
|
166
231
|
prerelease: false
|
167
|
-
version_requirements:
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ~>
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: 3.1.2
|
168
238
|
- !ruby/object:Gem::Dependency
|
169
239
|
name: rake
|
170
|
-
requirement:
|
240
|
+
requirement: !ruby/object:Gem::Requirement
|
171
241
|
none: false
|
172
242
|
requirements:
|
173
243
|
- - ! '>='
|
@@ -175,18 +245,60 @@ dependencies:
|
|
175
245
|
version: '0'
|
176
246
|
type: :development
|
177
247
|
prerelease: false
|
178
|
-
version_requirements:
|
179
|
-
- !ruby/object:Gem::Dependency
|
180
|
-
name: debugger
|
181
|
-
requirement: &70266014377280 !ruby/object:Gem::Requirement
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
182
249
|
none: false
|
183
250
|
requirements:
|
184
251
|
- - ! '>='
|
185
252
|
- !ruby/object:Gem::Version
|
186
253
|
version: '0'
|
254
|
+
- !ruby/object:Gem::Dependency
|
255
|
+
name: timecop
|
256
|
+
requirement: !ruby/object:Gem::Requirement
|
257
|
+
none: false
|
258
|
+
requirements:
|
259
|
+
- - ~>
|
260
|
+
- !ruby/object:Gem::Version
|
261
|
+
version: 0.3.5
|
187
262
|
type: :development
|
188
263
|
prerelease: false
|
189
|
-
version_requirements:
|
264
|
+
version_requirements: !ruby/object:Gem::Requirement
|
265
|
+
none: false
|
266
|
+
requirements:
|
267
|
+
- - ~>
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
version: 0.3.5
|
270
|
+
- !ruby/object:Gem::Dependency
|
271
|
+
name: webmock
|
272
|
+
requirement: !ruby/object:Gem::Requirement
|
273
|
+
none: false
|
274
|
+
requirements:
|
275
|
+
- - ~>
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: 1.8.7
|
278
|
+
type: :development
|
279
|
+
prerelease: false
|
280
|
+
version_requirements: !ruby/object:Gem::Requirement
|
281
|
+
none: false
|
282
|
+
requirements:
|
283
|
+
- - ~>
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: 1.8.7
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: mocha
|
288
|
+
requirement: !ruby/object:Gem::Requirement
|
289
|
+
none: false
|
290
|
+
requirements:
|
291
|
+
- - ~>
|
292
|
+
- !ruby/object:Gem::Version
|
293
|
+
version: 0.12.0
|
294
|
+
type: :development
|
295
|
+
prerelease: false
|
296
|
+
version_requirements: !ruby/object:Gem::Requirement
|
297
|
+
none: false
|
298
|
+
requirements:
|
299
|
+
- - ~>
|
300
|
+
- !ruby/object:Gem::Version
|
301
|
+
version: 0.12.0
|
190
302
|
description: A websocket service compatible with Pusher libraries
|
191
303
|
email: sjtgraham@mac.com
|
192
304
|
executables:
|
@@ -208,9 +320,9 @@ files:
|
|
208
320
|
- lib/slanger/service.rb
|
209
321
|
- lib/slanger/subscription.rb
|
210
322
|
- lib/slanger/web_socket_server.rb
|
323
|
+
- lib/slanger/webhook.rb
|
211
324
|
- slanger.rb
|
212
|
-
-
|
213
|
-
YmluL3NsYW5nZXI=
|
325
|
+
- bin/slanger
|
214
326
|
homepage: http://github.com/stevegraham/slanger
|
215
327
|
licenses: []
|
216
328
|
post_install_message:
|
@@ -231,9 +343,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
343
|
version: '0'
|
232
344
|
requirements: []
|
233
345
|
rubyforge_project:
|
234
|
-
rubygems_version: 1.8.
|
346
|
+
rubygems_version: 1.8.24
|
235
347
|
signing_key:
|
236
348
|
specification_version: 3
|
237
349
|
summary: A websocket service compatible with Pusher libraries
|
238
350
|
test_files: []
|
239
|
-
has_rdoc:
|