faye-tls1-websocket 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +117 -0
- data/README.md +473 -0
- data/examples/app.rb +53 -0
- data/examples/autobahn_client.rb +51 -0
- data/examples/client.rb +32 -0
- data/examples/config.ru +14 -0
- data/examples/haproxy.conf +21 -0
- data/examples/rainbows.conf +3 -0
- data/examples/server.rb +53 -0
- data/examples/sse.html +39 -0
- data/examples/ws.html +44 -0
- data/lib/faye/adapters/goliath.rb +47 -0
- data/lib/faye/adapters/rainbows.rb +31 -0
- data/lib/faye/adapters/rainbows_client.rb +69 -0
- data/lib/faye/adapters/thin.rb +62 -0
- data/lib/faye/eventsource.rb +121 -0
- data/lib/faye/rack_stream.rb +70 -0
- data/lib/faye/websocket.rb +100 -0
- data/lib/faye/websocket/adapter.rb +21 -0
- data/lib/faye/websocket/api.rb +115 -0
- data/lib/faye/websocket/api/event.rb +33 -0
- data/lib/faye/websocket/api/event_target.rb +57 -0
- data/lib/faye/websocket/client.rb +64 -0
- metadata +232 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2bc70be4a950f1731bd5c326674cfdc9eb482a48
|
4
|
+
data.tar.gz: 619b3f0f4fb03cb6ffeb5bc50a5ec32732b169c9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba64e50cb442e79ceac7c5f32b652793a5d5dc2c2fec125fb157eff3b09913ed958288361e29f56aae55f04c6c8d15dd85715e5dc1455b73bf9b35e4dbfb704e
|
7
|
+
data.tar.gz: 6d3adc8886f366437d415f04ba6cfaa473309208f5140a6a3b66acd5c1f4c7acd4788185331312e3892bb3b54672b6c96bbc184f571adf4b2b2e221e4bf7cc54
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
### 0.7.2 / 2013-12-29
|
2
|
+
|
3
|
+
* Fix WebSocket detection in cases where the web server does not produce an `env`
|
4
|
+
|
5
|
+
|
6
|
+
### 0.7.1 / 2013-12-03
|
7
|
+
|
8
|
+
* Support the `max_length` websocket-driver option
|
9
|
+
* Expose a `message` property on `error` events
|
10
|
+
|
11
|
+
|
12
|
+
### 0.7.0 / 2013-09-09
|
13
|
+
|
14
|
+
* Allow the server to send custom headers with EventSource responses
|
15
|
+
|
16
|
+
|
17
|
+
### 0.6.3 / 2013-08-04
|
18
|
+
|
19
|
+
* Stop implicitly depending on Rack 1.4
|
20
|
+
|
21
|
+
|
22
|
+
### 0.6.2 / 2013-07-05
|
23
|
+
|
24
|
+
* Catch errors thrown by EventMachine and emit `error` and `close` events
|
25
|
+
|
26
|
+
|
27
|
+
### 0.6.1 / 2013-05-12
|
28
|
+
|
29
|
+
* Release a gem without log and pid files in it
|
30
|
+
|
31
|
+
|
32
|
+
### 0.6.0 / 2013-05-12
|
33
|
+
|
34
|
+
* Add support for custom headers
|
35
|
+
|
36
|
+
|
37
|
+
### 0.5.0 / 2013-05-05
|
38
|
+
|
39
|
+
* Extract the protocol handlers into the `websocket-driver` library
|
40
|
+
* Support the `rack.hijack` API
|
41
|
+
* Add support for Rainbows 4.5 and Puma
|
42
|
+
* Officially support JRuby and Rubinius
|
43
|
+
|
44
|
+
|
45
|
+
### 0.4.7 / 2013-02-14
|
46
|
+
|
47
|
+
* Emit the `close` event if TCP is closed before CLOSE frame is acked
|
48
|
+
* Treat the `Upgrade: websocket` header case-insensitively because of IE10
|
49
|
+
* Do not suppress headers in the Thin and Rainbows adapters unless the status is `101`
|
50
|
+
|
51
|
+
|
52
|
+
### 0.4.6 / 2012-07-09
|
53
|
+
|
54
|
+
* Add `Connection: close` to EventSource response
|
55
|
+
|
56
|
+
|
57
|
+
### 0.4.5 / 2012-04-06
|
58
|
+
|
59
|
+
* Add WebSocket error code `1011`.
|
60
|
+
* Handle URLs with no path correctly by sending `GET /`
|
61
|
+
|
62
|
+
|
63
|
+
### 0.4.4 / 2012-03-16
|
64
|
+
|
65
|
+
* Fix installation on JRuby with a platform-specific gem
|
66
|
+
|
67
|
+
|
68
|
+
### 0.4.3 / 2012-03-12
|
69
|
+
|
70
|
+
* Make `extconf.rb` a no-op on JRuby
|
71
|
+
|
72
|
+
|
73
|
+
### 0.4.2 / 2012-03-09
|
74
|
+
|
75
|
+
* Port masking-function C extension to Java for JRuby
|
76
|
+
|
77
|
+
|
78
|
+
### 0.4.1 / 2012-02-26
|
79
|
+
|
80
|
+
* Treat anything other than an `Array` as a string when calling `send()`
|
81
|
+
* Fix error loading UTF-8 validation code on Ruby 1.9 with `-Ku` flag
|
82
|
+
|
83
|
+
|
84
|
+
### 0.4.0 / 2012-02-13
|
85
|
+
|
86
|
+
* Add `ping()` method to server-side `WebSocket` and `EventSource`
|
87
|
+
* Buffer `send()` calls until the draft-76 handshake is complete
|
88
|
+
|
89
|
+
|
90
|
+
### 0.3.0 / 2012-01-13
|
91
|
+
|
92
|
+
* Add support for `EventSource` connections
|
93
|
+
* Support the Thin, Rainbows and Goliath web servers
|
94
|
+
|
95
|
+
|
96
|
+
### 0.2.0 / 2011-12-21
|
97
|
+
|
98
|
+
* Add support for `Sec-WebSocket-Protocol` negotiation
|
99
|
+
* Support `hixie-76` close frames and 75/76 ignored segments
|
100
|
+
* Improve performance of HyBi parsing/framing functions
|
101
|
+
* Write masking function in C
|
102
|
+
|
103
|
+
|
104
|
+
### 0.1.2 / 2011-12-05
|
105
|
+
|
106
|
+
* Make `hixie-76` sockets work through HAProxy
|
107
|
+
|
108
|
+
|
109
|
+
### 0.1.1 / 2011-11-30
|
110
|
+
|
111
|
+
* Fix `add_event_listener()` interface methods
|
112
|
+
|
113
|
+
|
114
|
+
### 0.1.0 / 2011-11-27
|
115
|
+
|
116
|
+
* Initial release, based on WebSocket components from Faye
|
117
|
+
|
data/README.md
ADDED
@@ -0,0 +1,473 @@
|
|
1
|
+
# faye-websocket
|
2
|
+
|
3
|
+
* Travis CI build: [![Build
|
4
|
+
status](https://secure.travis-ci.org/faye/faye-websocket-ruby.png)](http://travis-ci.org/faye/faye-websocket-ruby)
|
5
|
+
* Autobahn tests: [server](http://faye.jcoglan.com/autobahn/servers/),
|
6
|
+
[client](http://faye.jcoglan.com/autobahn/clients/)
|
7
|
+
|
8
|
+
This is a general-purpose WebSocket implementation extracted from the
|
9
|
+
[Faye](http://faye.jcoglan.com) project. It provides classes for easily
|
10
|
+
building WebSocket servers and clients in Ruby. It does not provide a server
|
11
|
+
itself, but rather makes it easy to handle WebSocket connections within an
|
12
|
+
existing [Rack](http://rack.rubyforge.org/) application. It does not provide
|
13
|
+
any abstraction other than the standard [WebSocket
|
14
|
+
API](http://dev.w3.org/html5/websockets/).
|
15
|
+
|
16
|
+
It also provides an abstraction for handling
|
17
|
+
[EventSource](http://dev.w3.org/html5/eventsource/) connections, which are
|
18
|
+
one-way connections that allow the server to push data to the client. They are
|
19
|
+
based on streaming HTTP responses and can be easier to access via proxies than
|
20
|
+
WebSockets.
|
21
|
+
|
22
|
+
The following web servers are supported. Other servers that implement the
|
23
|
+
`rack.hjiack` API should also work.
|
24
|
+
|
25
|
+
* [Goliath](http://postrank-labs.github.com/goliath/)
|
26
|
+
* [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4
|
27
|
+
* [Puma](http://puma.io/) >= 2.0
|
28
|
+
* [Rainbows](http://rainbows.rubyforge.org/)
|
29
|
+
* [Thin](http://code.macournoyer.com/thin/)
|
30
|
+
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
```
|
35
|
+
$ gem install faye-websocket
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
## Handling WebSocket connections in Rack
|
40
|
+
|
41
|
+
You can handle WebSockets on the server side by listening for requests using
|
42
|
+
the `Faye::WebSocket.websocket?` method, and creating a new socket for the
|
43
|
+
request. This socket object exposes the usual WebSocket methods for receiving
|
44
|
+
and sending messages. For example this is how you'd implement an echo server:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
# app.rb
|
48
|
+
require 'faye/websocket'
|
49
|
+
|
50
|
+
App = lambda do |env|
|
51
|
+
if Faye::WebSocket.websocket?(env)
|
52
|
+
ws = Faye::WebSocket.new(env)
|
53
|
+
|
54
|
+
ws.on :message do |event|
|
55
|
+
ws.send(event.data)
|
56
|
+
end
|
57
|
+
|
58
|
+
ws.on :close do |event|
|
59
|
+
p [:close, event.code, event.reason]
|
60
|
+
ws = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return async Rack response
|
64
|
+
ws.rack_response
|
65
|
+
|
66
|
+
else
|
67
|
+
# Normal HTTP request
|
68
|
+
[200, {'Content-Type' => 'text/plain'}, ['Hello']]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
Note that under certain circumstances (notably a draft-76 client connecting
|
74
|
+
through an HTTP proxy), the WebSocket handshake will not be complete after you
|
75
|
+
call `Faye::WebSocket.new` because the server will not have received the entire
|
76
|
+
handshake from the client yet. In this case, calls to `ws.send` will buffer the
|
77
|
+
message in memory until the handshake is complete, at which point any buffered
|
78
|
+
messages will be sent to the client.
|
79
|
+
|
80
|
+
If you need to detect when the WebSocket handshake is complete, you can use the
|
81
|
+
`onopen` event.
|
82
|
+
|
83
|
+
If the connection's protocol version supports it, you can call `ws.ping()` to
|
84
|
+
send a ping message and wait for the client's response. This method takes a
|
85
|
+
message string, and an optional callback that fires when a matching pong
|
86
|
+
message is received. It returns `true` iff a ping message was sent. If the
|
87
|
+
client does not support ping/pong, this method sends no data and returns
|
88
|
+
`false`.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
ws.ping 'Mic check, one, two' do
|
92
|
+
# fires when pong is received
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
|
97
|
+
## Using the WebSocket client
|
98
|
+
|
99
|
+
The client supports both the plain-text `ws` protocol and the encrypted `wss`
|
100
|
+
protocol, and has exactly the same interface as a socket you would use in a web
|
101
|
+
browser. On the wire it identifies itself as `hybi-13`.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
require 'faye/websocket'
|
105
|
+
require 'eventmachine'
|
106
|
+
|
107
|
+
EM.run {
|
108
|
+
ws = Faye::WebSocket::Client.new('ws://www.example.com/')
|
109
|
+
|
110
|
+
ws.on :open do |event|
|
111
|
+
p [:open]
|
112
|
+
ws.send('Hello, world!')
|
113
|
+
end
|
114
|
+
|
115
|
+
ws.on :message do |event|
|
116
|
+
p [:message, event.data]
|
117
|
+
end
|
118
|
+
|
119
|
+
ws.on :close do |event|
|
120
|
+
p [:close, event.code, event.reason]
|
121
|
+
ws = nil
|
122
|
+
end
|
123
|
+
}
|
124
|
+
```
|
125
|
+
|
126
|
+
The WebSocket client also lets you inspect the status and headers of the
|
127
|
+
handshake response via its `status` and `headers` methods.
|
128
|
+
|
129
|
+
|
130
|
+
## Subprotocol negotiation
|
131
|
+
|
132
|
+
The WebSocket protocol allows peers to select and identify the application
|
133
|
+
protocol to use over the connection. On the client side, you can set which
|
134
|
+
protocols the client accepts by passing a list of protocol names when you
|
135
|
+
construct the socket:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
ws = Faye::WebSocket::Client.new('ws://www.example.com/', ['irc', 'amqp'])
|
139
|
+
```
|
140
|
+
|
141
|
+
On the server side, you can likewise pass in the list of protocols the server
|
142
|
+
supports after the other constructor arguments:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
ws = Faye::WebSocket.new(env, ['irc', 'amqp'])
|
146
|
+
```
|
147
|
+
|
148
|
+
If the client and server agree on a protocol, both the client- and server-side
|
149
|
+
socket objects expose the selected protocol through the `ws.protocol` property.
|
150
|
+
|
151
|
+
|
152
|
+
## Initialization options
|
153
|
+
|
154
|
+
Both the server- and client-side classes allow an options hash to be passed in
|
155
|
+
at initialization time, for example:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
ws = Faye::WebSocket.new(env, protocols, options)
|
159
|
+
ws = Faye::WebSocket::Client.new(url, protocols, options)
|
160
|
+
```
|
161
|
+
|
162
|
+
`protocols` as an array of subprotocols as described above, or `nil`. `options`
|
163
|
+
is an optional hash containing any of these keys:
|
164
|
+
|
165
|
+
* `:headers` - a hash containing key-value pairs representing HTTP headers to
|
166
|
+
be sent during the handshake process
|
167
|
+
* `:max_length` - the maximum allowed size of incoming message frames, in bytes.
|
168
|
+
The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
|
169
|
+
* `:ping` - an integer that sets how often the WebSocket should send ping
|
170
|
+
frames, measured in seconds
|
171
|
+
|
172
|
+
|
173
|
+
## WebSocket API
|
174
|
+
|
175
|
+
Both the server- and client-side `WebSocket` objects support the following API:
|
176
|
+
|
177
|
+
* <b>`on(:open) { |event| }`</b> fires when the socket connection is
|
178
|
+
established. Event has no attributes.
|
179
|
+
* <b>`on(:message) { |event| }`</b> fires when the socket receives a message.
|
180
|
+
Event has one attribute, <b>`data`</b>, which is either a `String` (for text
|
181
|
+
frames) or an `Array` of byte-sized integers (for binary frames).
|
182
|
+
* <b>`on(:error) { |event| }`</b> fires when there is a protocol error due to
|
183
|
+
bad data sent by the other peer. This event is purely informational, you do
|
184
|
+
not need to implement error recovery.
|
185
|
+
* <b>`on(:close) { |event| }`</b> fires when either the client or the server
|
186
|
+
closes the connection. Event has two optional attributes, <b>`code`</b> and
|
187
|
+
<b>`reason`</b>, that expose the status code and message sent by the peer
|
188
|
+
that closed the connection.
|
189
|
+
* <b>`send(message)`</b> accepts either a `String` or an `Array` of byte-sized
|
190
|
+
integers and sends a text or binary message over the connection to the other
|
191
|
+
peer.
|
192
|
+
* <b>`ping(message = '', &callback)`</b> sends a ping frame with an optional
|
193
|
+
message and fires the callback when a matching pong is received.
|
194
|
+
* <b>`close`</b> closes the connection.
|
195
|
+
* <b>`version`</b> is a string containing the version of the `WebSocket`
|
196
|
+
protocol the connection is using.
|
197
|
+
* <b>`protocol`</b> is a string (which may be empty) identifying the
|
198
|
+
subprotocol the socket is using.
|
199
|
+
|
200
|
+
|
201
|
+
## Handling EventSource connections in Rack
|
202
|
+
|
203
|
+
EventSource connections provide a very similar interface, although because they
|
204
|
+
only allow the server to send data to the client, there is no `onmessage` API.
|
205
|
+
EventSource allows the server to push text messages to the client, where each
|
206
|
+
message has an optional event-type and ID.
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
# app.rb
|
210
|
+
require 'faye/websocket'
|
211
|
+
|
212
|
+
App = lambda do |env|
|
213
|
+
if Faye::EventSource.eventsource?(env)
|
214
|
+
es = Faye::EventSource.new(env)
|
215
|
+
p [:open, es.url, es.last_event_id]
|
216
|
+
|
217
|
+
# Periodically send messages
|
218
|
+
loop = EM.add_periodic_timer(1) { es.send('Hello') }
|
219
|
+
|
220
|
+
es.on :close do |event|
|
221
|
+
EM.cancel_timer(loop)
|
222
|
+
es = nil
|
223
|
+
end
|
224
|
+
|
225
|
+
# Return async Rack response
|
226
|
+
es.rack_response
|
227
|
+
|
228
|
+
else
|
229
|
+
# Normal HTTP request
|
230
|
+
[200, {'Content-Type' => 'text/plain'}, ['Hello']]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
The `send` method takes two optional parameters, `:event` and `:id`. The
|
236
|
+
default event-type is `'message'` with no ID. For example, to send a
|
237
|
+
`notification` event with ID `99`:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
es.send('Breaking News!', :event => 'notification', :id => '99')
|
241
|
+
```
|
242
|
+
|
243
|
+
The `EventSource` object exposes the following properties:
|
244
|
+
|
245
|
+
* <b>`url`</b> is a string containing the URL the client used to create the
|
246
|
+
EventSource.
|
247
|
+
* <b>`last_event_id`</b> is a string containing the last event ID received by
|
248
|
+
the client. You can use this when the client reconnects after a dropped
|
249
|
+
connection to determine which messages need resending.
|
250
|
+
|
251
|
+
When you initialize an EventSource with `Faye::EventSource.new`, you can pass
|
252
|
+
configuration options after the `env` parameter. Available options are:
|
253
|
+
|
254
|
+
* <b>`:headers`</b> is a hash containing custom headers to be set on the
|
255
|
+
EventSource response.
|
256
|
+
* <b>`:retry`</b> is a number that tells the client how long (in seconds) it
|
257
|
+
should wait after a dropped connection before attempting to reconnect.
|
258
|
+
* <b>`:ping`</b> is a number that tells the server how often (in seconds) to
|
259
|
+
send 'ping' packets to the client to keep the connection open, to defeat
|
260
|
+
timeouts set by proxies. The client will ignore these messages.
|
261
|
+
|
262
|
+
For example, this creates a connection that allows access from any origin, pings
|
263
|
+
every 15 seconds and is retryable every 10 seconds if the connection is broken:
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
es = Faye::EventSource.new(es,
|
267
|
+
:headers => {'Access-Control-Allow-Origin' => '*'},
|
268
|
+
:ping => 15,
|
269
|
+
:retry => 10
|
270
|
+
)
|
271
|
+
```
|
272
|
+
|
273
|
+
You can send a ping message at any time by calling `es.ping`. Unlike WebSocket
|
274
|
+
the client does not send a response to this; it is merely to send some data
|
275
|
+
over the wire to keep the connection alive.
|
276
|
+
|
277
|
+
|
278
|
+
## Running your socket application
|
279
|
+
|
280
|
+
The following describes how to run a WebSocket application using all our
|
281
|
+
supported web servers.
|
282
|
+
|
283
|
+
|
284
|
+
### Running the app with Thin
|
285
|
+
|
286
|
+
If you use Thin to serve your application you need to include this line after
|
287
|
+
loading `faye/websocket`:
|
288
|
+
|
289
|
+
```ruby
|
290
|
+
Faye::WebSocket.load_adapter('thin')
|
291
|
+
```
|
292
|
+
|
293
|
+
Thin can be started via the command line if you've set up a `config.ru` file
|
294
|
+
for your application:
|
295
|
+
|
296
|
+
```
|
297
|
+
$ thin start -R config.ru -p 9292
|
298
|
+
```
|
299
|
+
|
300
|
+
Or, you can use `rackup`. In development mode, this adds middlewares that don't
|
301
|
+
work with async apps, so you must start it in production mode:
|
302
|
+
|
303
|
+
```
|
304
|
+
$ rackup config.ru -s thin -E production -p 9292
|
305
|
+
```
|
306
|
+
|
307
|
+
It can also be started using the `Rack::Handler` interface common to many Ruby
|
308
|
+
servers. It must be run using EventMachine, and you can configure Thin further
|
309
|
+
in a block passed to `run`:
|
310
|
+
|
311
|
+
```ruby
|
312
|
+
require 'eventmachine'
|
313
|
+
require 'rack'
|
314
|
+
require 'thin'
|
315
|
+
require './app'
|
316
|
+
|
317
|
+
Faye::WebSocket.load_adapter('thin')
|
318
|
+
|
319
|
+
EM.run {
|
320
|
+
thin = Rack::Handler.get('thin')
|
321
|
+
|
322
|
+
thin.run(App, :Port => 9292) do |server|
|
323
|
+
# You can set options on the server here, for example to set up SSL:
|
324
|
+
server.ssl_options = {
|
325
|
+
:private_key_file => 'path/to/ssl.key',
|
326
|
+
:cert_chain_file => 'path/to/ssl.crt'
|
327
|
+
}
|
328
|
+
server.ssl = true
|
329
|
+
end
|
330
|
+
}
|
331
|
+
```
|
332
|
+
|
333
|
+
|
334
|
+
### Running the app with Passenger
|
335
|
+
|
336
|
+
faye-websocket requires either Passenger for Nginx or Passenger Standalone.
|
337
|
+
Apache doesn't work well with WebSockets at this time. You do not need any
|
338
|
+
special configuration to make faye-websocket work, it should work out of the
|
339
|
+
box on Passenger provided you use at least Passenger 4.0.
|
340
|
+
|
341
|
+
Run your app on Passenger for Nginx by creating a virtual host entry which
|
342
|
+
points to your app's "public" directory:
|
343
|
+
|
344
|
+
```
|
345
|
+
server {
|
346
|
+
listen 9292;
|
347
|
+
server_name yourdomain.local;
|
348
|
+
root /path-to-your-app/public;
|
349
|
+
passenger_enabled on;
|
350
|
+
}
|
351
|
+
```
|
352
|
+
|
353
|
+
Or run your app on Passenger Standalone:
|
354
|
+
|
355
|
+
```
|
356
|
+
$ passenger start -p 9292
|
357
|
+
```
|
358
|
+
|
359
|
+
More information can be found on [the Passenger
|
360
|
+
website](https://www.phusionpassenger.com/support).
|
361
|
+
|
362
|
+
|
363
|
+
### Running the app with Puma
|
364
|
+
|
365
|
+
Puma has a command line interface for starting your application:
|
366
|
+
|
367
|
+
```
|
368
|
+
$ puma config.ru -p 9292
|
369
|
+
```
|
370
|
+
|
371
|
+
Or, you can use `rackup`. In development mode, this adds middlewares that don't
|
372
|
+
work with async apps, so you must start it in production mode:
|
373
|
+
|
374
|
+
```
|
375
|
+
$ rackup config.ru -s puma -E production -p 9292
|
376
|
+
```
|
377
|
+
|
378
|
+
|
379
|
+
### Running the app with Rainbows
|
380
|
+
|
381
|
+
If you're using version 4.4 or lower of Rainbows, you need to run it with the
|
382
|
+
EventMachine backend and enable the adapter. Put this in your `rainbows.conf`
|
383
|
+
file:
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
Rainbows! { use :EventMachine }
|
387
|
+
```
|
388
|
+
|
389
|
+
And make sure you load the adapter in your application:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
Faye::WebSocket.load_adapter('rainbows')
|
393
|
+
```
|
394
|
+
|
395
|
+
Version 4.5 of Rainbows does not need this adapter.
|
396
|
+
|
397
|
+
You can run your `config.ru` file from the command line. Again, `Rack::Lint`
|
398
|
+
will complain unless you put the application in production mode.
|
399
|
+
|
400
|
+
```
|
401
|
+
$ rainbows config.ru -c path/to/rainbows.conf -E production -p 9292
|
402
|
+
```
|
403
|
+
|
404
|
+
|
405
|
+
### Running the app with Goliath
|
406
|
+
|
407
|
+
If you use Goliath to server your application you need to include this line
|
408
|
+
after loading `faye/websocket`:
|
409
|
+
|
410
|
+
```ruby
|
411
|
+
Faye::WebSocket.load_adapter('goliath')
|
412
|
+
```
|
413
|
+
|
414
|
+
Goliath can be made to run arbitrary Rack apps by delegating to them from a
|
415
|
+
`Goliath::API` instance. A simple server looks like this:
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
require 'goliath'
|
419
|
+
require './app'
|
420
|
+
Faye::WebSocket.load_adapter('goliath')
|
421
|
+
|
422
|
+
class EchoServer < Goliath::API
|
423
|
+
def response(env)
|
424
|
+
App.call(env)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
```
|
428
|
+
|
429
|
+
`Faye::WebSocket` can also be used inline within a Goliath app:
|
430
|
+
|
431
|
+
```ruby
|
432
|
+
require 'goliath'
|
433
|
+
require 'faye/websocket'
|
434
|
+
Faye::WebSocket.load_adapter('goliath')
|
435
|
+
|
436
|
+
class EchoServer < Goliath::API
|
437
|
+
def response(env)
|
438
|
+
ws = Faye::WebSocket.new(env)
|
439
|
+
|
440
|
+
ws.on :message do |event|
|
441
|
+
ws.send(event.data)
|
442
|
+
end
|
443
|
+
|
444
|
+
ws.rack_response
|
445
|
+
end
|
446
|
+
end
|
447
|
+
```
|
448
|
+
|
449
|
+
|
450
|
+
## License
|
451
|
+
|
452
|
+
(The MIT License)
|
453
|
+
|
454
|
+
Copyright (c) 2010-2013 James Coglan
|
455
|
+
|
456
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
457
|
+
this software and associated documentation files (the 'Software'), to deal in
|
458
|
+
the Software without restriction, including without limitation the rights to
|
459
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
460
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
461
|
+
so, subject to the following conditions:
|
462
|
+
|
463
|
+
The above copyright notice and this permission notice shall be included in all
|
464
|
+
copies or substantial portions of the Software.
|
465
|
+
|
466
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
467
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
468
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
469
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
470
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
471
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
472
|
+
SOFTWARE.
|
473
|
+
|