slanger 0.1.0 → 0.1.1
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 +91 -0
- metadata +32 -31
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# Slanger
|
2
|
+
|
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.
|
4
|
+
|
5
|
+
Presence channel state is shared using Redis. Channels are lazily instantiated internally within a given Slanger node when the first subscriber connects. When a presence channel is instantiated within a Slanger node, it queries Redis for the global state across all nodes within the system for that channel, and then copies that state internally. Afterwards, when subscribers connect or disconnect the node publishes a presence message to all interested nodes, i.e. all nodes with at least one subscriber interested in the given channel.
|
6
|
+
|
7
|
+
Slanger is smart enough to know if a new channel subscription belongs to the same user. It will not send presence messages to subscribers in this case. This happens when the user has multiple browser tabs open for example. Using a chat room backed by presence channels as a real example, one would not want "Micheil" to show up N times in the presence roster because Micheil is a retard and has the chat room open in N browser tabs.
|
8
|
+
|
9
|
+
Slanger was designed to be highly available and partition tolerant with eventual consistency, which in practise is instantaneous.
|
10
|
+
|
11
|
+
# How to use it
|
12
|
+
|
13
|
+
## Requirements
|
14
|
+
|
15
|
+
- Ruby 1.9
|
16
|
+
- Redis
|
17
|
+
|
18
|
+
## Starting the service
|
19
|
+
|
20
|
+
Slanger is packaged as a Rubygem. Installing the gem makes the 'slanger' executable available. The `slanger` executable takes arguments, of which two are mandatory: `--app_key` and `--secret`. These can but do not have to be the same as the credentials you use for Pusher. They are required because Slanger performs the same HMAC signing of API requests that Pusher does.
|
21
|
+
|
22
|
+
__IMPORTANT:__ Redis must be running where Slanger expects it to be (either on localhost:6379 or somewhere else you told Slanger it would be using the option flag) or Slanger will fail silently. I haven't yet figured out how to get em-hiredis to treat an unreachable host as an error
|
23
|
+
|
24
|
+
<pre>
|
25
|
+
$ gem install slanger
|
26
|
+
|
27
|
+
$ redis-server 1>2 &
|
28
|
+
|
29
|
+
$ slanger --app_key 765ec374ae0a69f4ce44 --secret your-pusher-secret
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
If all went to plan you should see the following output to STDOUT
|
33
|
+
|
34
|
+
<pre>
|
35
|
+
|
36
|
+
.d8888b. 888
|
37
|
+
d88P Y88b 888
|
38
|
+
Y88b. 888
|
39
|
+
"Y888b. 888 8888b. 88888b. .d88b. .d88b. 888d888
|
40
|
+
"Y88b. 888 "88b 888 "88b d88P"88b d8P Y8b 888P"
|
41
|
+
"888 888 .d888888 888 888 888 888 88888888 888
|
42
|
+
Y88b d88P 888 888 888 888 888 Y88b 888 Y8b. 888
|
43
|
+
"Y8888P" 888 "Y888888 888 888 "Y88888 "Y8888 888
|
44
|
+
888
|
45
|
+
Y8b d88P
|
46
|
+
"Y88P"
|
47
|
+
|
48
|
+
|
49
|
+
Slanger API server listening on port 4567
|
50
|
+
Slanger WebSocket server listening on port 8080
|
51
|
+
|
52
|
+
</pre>
|
53
|
+
|
54
|
+
## Modifying your application code to use the Slanger service
|
55
|
+
|
56
|
+
Once you have a Slanger instance listening for incoming connections you need to alter you application code to use the Slanger endpoint instead of Pusher. Fortunately this is very simple, unobtrusive, easily reversable, and very painless.
|
57
|
+
|
58
|
+
|
59
|
+
First you will need to add code to your server side component that publishes events to the Pusher HTTP REST API, usually this means telling the Pusher client to use a different host and port, e.g. consider this Ruby example
|
60
|
+
|
61
|
+
<pre>
|
62
|
+
...
|
63
|
+
|
64
|
+
Pusher.host = 'slanger.example.com'
|
65
|
+
Pusher.port = 4567
|
66
|
+
|
67
|
+
</pre>
|
68
|
+
|
69
|
+
You will also need to do the same to the Pusher JavaScript client in your client side JavaScript, e.g
|
70
|
+
|
71
|
+
<pre>
|
72
|
+
|
73
|
+
<script type="text/javascript">
|
74
|
+
...
|
75
|
+
|
76
|
+
Pusher.host = 'slanger.example.com'
|
77
|
+
Pusher.ws_port = 8080
|
78
|
+
|
79
|
+
</script>
|
80
|
+
</pre>
|
81
|
+
|
82
|
+
Of course you could proxy all requests to `ws.example.com` to port 8080 of your Slanger node and `api.example.com` to port 4567 of your Slanger node for example, that way you would only need to set the host property of the Pusher client.
|
83
|
+
|
84
|
+
# Why use Slanger instead of Pusher?
|
85
|
+
|
86
|
+
There are many reasons you might want to use Slanger instead of Pusher, e.g.
|
87
|
+
|
88
|
+
- You operate in a heavily regulated industry and are worried about sending data to 3rd parties, and it is an organisational requirement that you own your own infrastructure.
|
89
|
+
- You might be travelling on an airplane without internet connctivity as I am right now. Airplane rides are very good times to get a lot done, unfortunately external services are also usually unreachable. Remove internet connectivity as a dependendancy of your development envirionment by running a local Slanger instance in development and Pusher in production.
|
90
|
+
- You want to extend the Pusher protocol or have some special requirement. If this applies to you, chances are you are out of luck as Pusher is unlikely to implement something to suit your special use case, and rightly so. With Slanger you are free to modify and extend its behavior anyway that suits your purpose.
|
91
|
+
|
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.1.
|
4
|
+
version: 0.1.1
|
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: 2011-12-
|
12
|
+
date: 2011-12-13 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &70279989838940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.12.10
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70279989838940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: em-hiredis
|
27
|
-
requirement: &
|
27
|
+
requirement: &70279989865080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,21 +32,21 @@ dependencies:
|
|
32
32
|
version: 0.1.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70279989865080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: em-websocket
|
38
|
-
requirement: &
|
38
|
+
requirement: &70279989864620 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.3.
|
43
|
+
version: 0.3.5
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70279989864620
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack
|
49
|
-
requirement: &
|
49
|
+
requirement: &70279989864160 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.3.3
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70279989864160
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rack-fiber_pool
|
60
|
-
requirement: &
|
60
|
+
requirement: &70279989863700 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - =
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.9.1
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70279989863700
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: signature
|
71
|
-
requirement: &
|
71
|
+
requirement: &70279989863240 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.1.2
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70279989863240
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: activesupport
|
82
|
-
requirement: &
|
82
|
+
requirement: &70279989862780 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 3.1.0
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70279989862780
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: glamazon
|
93
|
-
requirement: &
|
93
|
+
requirement: &70279989862320 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: 0.3.1
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70279989862320
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: sinatra
|
104
|
-
requirement: &
|
104
|
+
requirement: &70279989861860 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: 1.2.6
|
110
110
|
type: :runtime
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70279989861860
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: thin
|
115
|
-
requirement: &
|
115
|
+
requirement: &70279989861400 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: 1.2.11
|
121
121
|
type: :runtime
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *70279989861400
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: em-http-request
|
126
|
-
requirement: &
|
126
|
+
requirement: &70279989860940 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,10 +131,10 @@ dependencies:
|
|
131
131
|
version: 0.3.0
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *70279989860940
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: rspec
|
137
|
-
requirement: &
|
137
|
+
requirement: &70279989860480 !ruby/object:Gem::Requirement
|
138
138
|
none: false
|
139
139
|
requirements:
|
140
140
|
- - ~>
|
@@ -142,10 +142,10 @@ dependencies:
|
|
142
142
|
version: 2.6.0
|
143
143
|
type: :development
|
144
144
|
prerelease: false
|
145
|
-
version_requirements: *
|
145
|
+
version_requirements: *70279989860480
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: pusher
|
148
|
-
requirement: &
|
148
|
+
requirement: &70279989860020 !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
@@ -153,10 +153,10 @@ dependencies:
|
|
153
153
|
version: 0.8.2
|
154
154
|
type: :development
|
155
155
|
prerelease: false
|
156
|
-
version_requirements: *
|
156
|
+
version_requirements: *70279989860020
|
157
157
|
- !ruby/object:Gem::Dependency
|
158
158
|
name: haml
|
159
|
-
requirement: &
|
159
|
+
requirement: &70279989859560 !ruby/object:Gem::Requirement
|
160
160
|
none: false
|
161
161
|
requirements:
|
162
162
|
- - ~>
|
@@ -164,7 +164,7 @@ dependencies:
|
|
164
164
|
version: 3.1.2
|
165
165
|
type: :development
|
166
166
|
prerelease: false
|
167
|
-
version_requirements: *
|
167
|
+
version_requirements: *70279989859560
|
168
168
|
description: A websocket service compatible with Pusher libraries
|
169
169
|
email: sjtgraham@mac.com
|
170
170
|
executables:
|
@@ -172,6 +172,7 @@ executables:
|
|
172
172
|
extensions: []
|
173
173
|
extra_rdoc_files: []
|
174
174
|
files:
|
175
|
+
- README.md
|
175
176
|
- lib/slanger/api_server.rb
|
176
177
|
- lib/slanger/channel.rb
|
177
178
|
- lib/slanger/config.rb
|