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.

Files changed (2) hide show
  1. data/README.md +91 -0
  2. metadata +32 -31
@@ -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.0
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 00:00:00.000000000Z
12
+ date: 2011-12-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70311444305760 !ruby/object:Gem::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: *70311444305760
24
+ version_requirements: *70279989838940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: em-hiredis
27
- requirement: &70311444305300 !ruby/object:Gem::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: *70311444305300
35
+ version_requirements: *70279989865080
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-websocket
38
- requirement: &70311444304840 !ruby/object:Gem::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.0
43
+ version: 0.3.5
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70311444304840
46
+ version_requirements: *70279989864620
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &70311444304380 !ruby/object:Gem::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: *70311444304380
57
+ version_requirements: *70279989864160
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rack-fiber_pool
60
- requirement: &70311444303920 !ruby/object:Gem::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: *70311444303920
68
+ version_requirements: *70279989863700
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: signature
71
- requirement: &70311444303460 !ruby/object:Gem::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: *70311444303460
79
+ version_requirements: *70279989863240
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: activesupport
82
- requirement: &70311444303000 !ruby/object:Gem::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: *70311444303000
90
+ version_requirements: *70279989862780
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: glamazon
93
- requirement: &70311444302540 !ruby/object:Gem::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: *70311444302540
101
+ version_requirements: *70279989862320
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: sinatra
104
- requirement: &70311444328700 !ruby/object:Gem::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: *70311444328700
112
+ version_requirements: *70279989861860
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: thin
115
- requirement: &70311444328240 !ruby/object:Gem::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: *70311444328240
123
+ version_requirements: *70279989861400
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: em-http-request
126
- requirement: &70311444327780 !ruby/object:Gem::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: *70311444327780
134
+ version_requirements: *70279989860940
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rspec
137
- requirement: &70311444327320 !ruby/object:Gem::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: *70311444327320
145
+ version_requirements: *70279989860480
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: pusher
148
- requirement: &70311444326860 !ruby/object:Gem::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: *70311444326860
156
+ version_requirements: *70279989860020
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: haml
159
- requirement: &70311444326400 !ruby/object:Gem::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: *70311444326400
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