websocket-driver 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +136 -0
- data/LICENSE.md +12 -0
- data/README.md +380 -0
- data/ext/websocket-driver/WebsocketMaskService.java +57 -0
- data/ext/websocket-driver/extconf.rb +4 -0
- data/ext/websocket-driver/websocket_mask.c +32 -0
- data/lib/websocket/driver.rb +233 -0
- data/lib/websocket/driver/client.rb +140 -0
- data/lib/websocket/driver/draft75.rb +102 -0
- data/lib/websocket/driver/draft76.rb +98 -0
- data/lib/websocket/driver/event_emitter.rb +54 -0
- data/lib/websocket/driver/headers.rb +45 -0
- data/lib/websocket/driver/hybi.rb +414 -0
- data/lib/websocket/driver/hybi/frame.rb +20 -0
- data/lib/websocket/driver/hybi/message.rb +31 -0
- data/lib/websocket/driver/proxy.rb +68 -0
- data/lib/websocket/driver/server.rb +80 -0
- data/lib/websocket/driver/stream_reader.rb +55 -0
- data/lib/websocket/http.rb +15 -0
- data/lib/websocket/http/headers.rb +112 -0
- data/lib/websocket/http/request.rb +45 -0
- data/lib/websocket/http/response.rb +29 -0
- data/lib/websocket/mask.rb +14 -0
- data/lib/websocket/websocket_mask.rb +2 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8b7a3b9878d6efb8ad25a608fd06548f4be94454406894588e15f856f4451746
|
4
|
+
data.tar.gz: a5f98cbda60d85887857b75a967ad8d33a41e549781739374865e05a76304e7b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fca692d01fb40ad07be65a0050923e03084841e995d53b3580bd84265b74c1a3411b8c4f16f0e319a2a9acb7811e48ad13bc43bc81023d308fb7ea385e150d0d
|
7
|
+
data.tar.gz: 48e438dea20c9dd8a90224ec32d3d16da1b04f145070e15d9bac741ad39717f04a246631df0475c266f28e495001f41d14f2534c118243075f8abc0921868524
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
### 0.7.1 / 2019-06-10
|
2
|
+
|
3
|
+
- Catch any exceptions produced while generating a handshake response and send a
|
4
|
+
`400 Bad Request` response to the client
|
5
|
+
- Pick the RFC-6455 protocol version if the request contains any of the headers
|
6
|
+
used by that version
|
7
|
+
- Handle errors encountered while handling malformed draft-76 requests
|
8
|
+
|
9
|
+
### 0.7.0 / 2017-09-11
|
10
|
+
|
11
|
+
- Add `ping` and `pong` to the set of events users can listen to
|
12
|
+
|
13
|
+
### 0.6.5 / 2017-01-22
|
14
|
+
|
15
|
+
- Provide a pure-Ruby fallback for the native unmasking code
|
16
|
+
|
17
|
+
### 0.6.4 / 2016-05-20
|
18
|
+
|
19
|
+
- Amend warnings issued when running with -W2
|
20
|
+
- Make sure message strings passed in by the app are transcoded to UTF-8
|
21
|
+
- Copy strings if necessary for frozen-string compatibility
|
22
|
+
|
23
|
+
### 0.6.3 / 2015-11-06
|
24
|
+
|
25
|
+
- Reject draft-76 handshakes if their Sec-WebSocket-Key headers are invalid
|
26
|
+
- Throw a more helpful error if a client is created with an invalid URL
|
27
|
+
|
28
|
+
### 0.6.2 / 2015-07-18
|
29
|
+
|
30
|
+
- When the peer sends a close frame with no error code, emit 1000
|
31
|
+
|
32
|
+
### 0.6.1 / 2015-07-13
|
33
|
+
|
34
|
+
- Fix how events are stored in `EventEmitter` to fix a backward-compatibility
|
35
|
+
violation introduced in the last release
|
36
|
+
- Use the `Array#pack` and `String#unpack` methods for reading/writing numbers
|
37
|
+
to buffers rather than including duplicate logic for this
|
38
|
+
|
39
|
+
### 0.6.0 / 2015-07-08
|
40
|
+
|
41
|
+
- Use `SecureRandom` to generate the `Sec-WebSocket-Key` header
|
42
|
+
- Allow the parser to recover cleanly if event listeners raise an error
|
43
|
+
- Let the `on()` method take a lambda as a positional argument rather than a
|
44
|
+
block
|
45
|
+
- Add a `pong` method for sending unsolicited pong frames
|
46
|
+
|
47
|
+
### 0.5.4 / 2015-03-29
|
48
|
+
|
49
|
+
- Don't emit extra close frames if we receive a close frame after we already
|
50
|
+
sent one
|
51
|
+
- Fail the connection when the driver receives an invalid
|
52
|
+
`Sec-WebSocket-Extensions` header
|
53
|
+
|
54
|
+
### 0.5.3 / 2015-02-22
|
55
|
+
|
56
|
+
- Don't treat incoming data as WebSocket frames if a client driver is closed
|
57
|
+
before receiving the server handshake
|
58
|
+
|
59
|
+
### 0.5.2 / 2015-02-19
|
60
|
+
|
61
|
+
- Don't emit multiple `error` events
|
62
|
+
|
63
|
+
### 0.5.1 / 2014-12-18
|
64
|
+
|
65
|
+
- Don't allow drivers to be created with unrecognized options
|
66
|
+
|
67
|
+
### 0.5.0 / 2014-12-13
|
68
|
+
|
69
|
+
- Support protocol extensions via the websocket-extensions module
|
70
|
+
|
71
|
+
### 0.4.0 / 2014-11-08
|
72
|
+
|
73
|
+
- Support connection via HTTP proxies using `CONNECT`
|
74
|
+
|
75
|
+
### 0.3.5 / 2014-10-04
|
76
|
+
|
77
|
+
- Fix bug where the `Server` driver doesn't pass `ping` callbacks to its
|
78
|
+
delegate
|
79
|
+
- Fix an arity error when calling `fail_request`
|
80
|
+
- Allow `close` to be called before `start` to close the driver
|
81
|
+
|
82
|
+
### 0.3.4 / 2014-07-06
|
83
|
+
|
84
|
+
- Don't hold references to frame buffers after a message has been emitted
|
85
|
+
- Make sure that `protocol` and `version` are exposed properly by the TCP driver
|
86
|
+
- Correct HTTP header parsing based on RFC 7230; header names cannot contain
|
87
|
+
backslashes
|
88
|
+
|
89
|
+
### 0.3.3 / 2014-04-24
|
90
|
+
|
91
|
+
- Fix problems with loading C and Java native extension code
|
92
|
+
- Correct the acceptable characters used in the HTTP parser
|
93
|
+
- Correct the draft-76 status line reason phrase
|
94
|
+
|
95
|
+
### 0.3.2 / 2013-12-29
|
96
|
+
|
97
|
+
- Expand `max_length` to cover sequences of continuation frames and
|
98
|
+
`draft-{75,76}`
|
99
|
+
- Decrease default maximum frame buffer size to 64MB
|
100
|
+
- Stop parsing when the protocol enters a failure mode, to save CPU cycles
|
101
|
+
|
102
|
+
### 0.3.1 / 2013-12-03
|
103
|
+
|
104
|
+
- Add a `max_length` option to limit allowed frame size
|
105
|
+
|
106
|
+
### 0.3.0 / 2013-09-09
|
107
|
+
|
108
|
+
- Support client URLs with Basic Auth credentials
|
109
|
+
|
110
|
+
### 0.2.3 / 2013-08-04
|
111
|
+
|
112
|
+
- Fix bug in EventEmitter#emit when listeners are removed
|
113
|
+
|
114
|
+
### 0.2.2 / 2013-08-04
|
115
|
+
|
116
|
+
- Fix bug in EventEmitter#listener_count for unregistered events
|
117
|
+
|
118
|
+
### 0.2.1 / 2013-07-05
|
119
|
+
|
120
|
+
- Queue sent messages if the client has not begun trying to connect
|
121
|
+
- Encode all strings sent to I/O as `ASCII-8BIT`
|
122
|
+
|
123
|
+
### 0.2.0 / 2013-05-12
|
124
|
+
|
125
|
+
- Add API for setting and reading headers
|
126
|
+
- Add Driver.server() method for getting a driver for TCP servers
|
127
|
+
|
128
|
+
### 0.1.0 / 2013-05-04
|
129
|
+
|
130
|
+
- First stable release
|
131
|
+
|
132
|
+
### 0.0.0 / 2013-04-22
|
133
|
+
|
134
|
+
- First release
|
135
|
+
- Proof of concept for people to try out
|
136
|
+
- Might be unstable
|
data/LICENSE.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Copyright 2010-2019 James Coglan
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
4
|
+
this file except in compliance with the License. You may obtain a copy of the
|
5
|
+
License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
10
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
11
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
12
|
+
specific language governing permissions and limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,380 @@
|
|
1
|
+
# websocket-driver [![Build Status](https://travis-ci.org/faye/websocket-driver-ruby.svg)](https://travis-ci.org/faye/websocket-driver-ruby)
|
2
|
+
|
3
|
+
This module provides a complete implementation of the WebSocket protocols that
|
4
|
+
can be hooked up to any TCP library. It aims to simplify things by decoupling
|
5
|
+
the protocol details from the I/O layer, such that users only need to implement
|
6
|
+
code to stream data in and out of it without needing to know anything about how
|
7
|
+
the protocol actually works. Think of it as a complete WebSocket system with
|
8
|
+
pluggable I/O.
|
9
|
+
|
10
|
+
Due to this design, you get a lot of things for free. In particular, if you hook
|
11
|
+
this module up to some I/O object, it will do all of this for you:
|
12
|
+
|
13
|
+
- Select the correct server-side driver to talk to the client
|
14
|
+
- Generate and send both server- and client-side handshakes
|
15
|
+
- Recognize when the handshake phase completes and the WS protocol begins
|
16
|
+
- Negotiate subprotocol selection based on `Sec-WebSocket-Protocol`
|
17
|
+
- Negotiate and use extensions via the
|
18
|
+
[websocket-extensions](https://github.com/faye/websocket-extensions-ruby)
|
19
|
+
module
|
20
|
+
- Buffer sent messages until the handshake process is finished
|
21
|
+
- Deal with proxies that defer delivery of the draft-76 handshake body
|
22
|
+
- Notify you when the socket is open and closed and when messages arrive
|
23
|
+
- Recombine fragmented messages
|
24
|
+
- Dispatch text, binary, ping, pong and close frames
|
25
|
+
- Manage the socket-closing handshake process
|
26
|
+
- Automatically reply to ping frames with a matching pong
|
27
|
+
- Apply masking to messages sent by the client
|
28
|
+
|
29
|
+
This library was originally extracted from the [Faye](http://faye.jcoglan.com)
|
30
|
+
project but now aims to provide simple WebSocket support for any Ruby server or
|
31
|
+
I/O system.
|
32
|
+
|
33
|
+
|
34
|
+
## Installation
|
35
|
+
|
36
|
+
```
|
37
|
+
$ gem install websocket-driver
|
38
|
+
```
|
39
|
+
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
To build either a server-side or client-side socket, the only requirement is
|
44
|
+
that you supply a `socket` object with these methods:
|
45
|
+
|
46
|
+
- `socket.url` - returns the full URL of the socket as a string.
|
47
|
+
- `socket.write(string)` - writes the given string to a TCP stream.
|
48
|
+
|
49
|
+
Server-side sockets require one additional method:
|
50
|
+
|
51
|
+
- `socket.env` - returns a Rack-style env hash that will contain some of the
|
52
|
+
following fields. Their values are strings containing the value of the named
|
53
|
+
header, unless stated otherwise.
|
54
|
+
* `HTTP_CONNECTION`
|
55
|
+
* `HTTP_HOST`
|
56
|
+
* `HTTP_ORIGIN`
|
57
|
+
* `HTTP_SEC_WEBSOCKET_EXTENSIONS`
|
58
|
+
* `HTTP_SEC_WEBSOCKET_KEY`
|
59
|
+
* `HTTP_SEC_WEBSOCKET_KEY1`
|
60
|
+
* `HTTP_SEC_WEBSOCKET_KEY2`
|
61
|
+
* `HTTP_SEC_WEBSOCKET_PROTOCOL`
|
62
|
+
* `HTTP_SEC_WEBSOCKET_VERSION`
|
63
|
+
* `HTTP_UPGRADE`
|
64
|
+
* `rack.input`, an `IO` object representing the request body
|
65
|
+
* `REQUEST_METHOD`, the request's HTTP verb
|
66
|
+
|
67
|
+
|
68
|
+
### Server-side with Rack
|
69
|
+
|
70
|
+
To handle a server-side WebSocket connection, you need to check whether the
|
71
|
+
request is a WebSocket handshake, and if so create a protocol driver for it.
|
72
|
+
You must give the driver an object with the `env`, `url` and `write` methods. A
|
73
|
+
simple example might be:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
require 'websocket/driver'
|
77
|
+
require 'eventmachine'
|
78
|
+
|
79
|
+
class WS
|
80
|
+
attr_reader :env, :url
|
81
|
+
|
82
|
+
def initialize(env)
|
83
|
+
@env = env
|
84
|
+
|
85
|
+
secure = Rack::Request.new(env).ssl?
|
86
|
+
scheme = secure ? 'wss:' : 'ws:'
|
87
|
+
@url = scheme + '//' + env['HTTP_HOST'] + env['REQUEST_URI']
|
88
|
+
|
89
|
+
@driver = WebSocket::Driver.rack(self)
|
90
|
+
|
91
|
+
env['rack.hijack'].call
|
92
|
+
@io = env['rack.hijack_io']
|
93
|
+
|
94
|
+
EM.attach(@io, Reader) { |conn| conn.driver = @driver }
|
95
|
+
|
96
|
+
@driver.start
|
97
|
+
end
|
98
|
+
|
99
|
+
def write(string)
|
100
|
+
@io.write(string)
|
101
|
+
end
|
102
|
+
|
103
|
+
module Reader
|
104
|
+
attr_writer :driver
|
105
|
+
|
106
|
+
def receive_data(string)
|
107
|
+
@driver.parse(string)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
To explain what's going on here: the `WS` class implements the `env`, `url` and
|
114
|
+
`write(string)` methods as required. When instantiated with a Rack environment,
|
115
|
+
it stores the environment and infers the complete URL from it. Having set up
|
116
|
+
the `env` and `url`, it asks `WebSocket::Driver` for a server-side driver for
|
117
|
+
the socket. Then it uses the Rack hijack API to gain access to the TCP stream,
|
118
|
+
and uses EventMachine to stream in incoming data from the client, handing
|
119
|
+
incoming data off to the driver for parsing. Finally, we tell the driver to
|
120
|
+
`start`, which will begin sending the handshake response. This will invoke the
|
121
|
+
`WS#write` method, which will send the response out over the TCP socket.
|
122
|
+
|
123
|
+
Having defined this class we could use it like this when handling a request:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
if WebSocket::Driver.websocket?(env)
|
127
|
+
socket = WS.new(env)
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
The driver API is described in full below.
|
132
|
+
|
133
|
+
|
134
|
+
### Server-side with TCP
|
135
|
+
|
136
|
+
You can also handle WebSocket connections in a bare TCP server, if you're not
|
137
|
+
using Rack and don't want to implement HTTP parsing yourself. For this, your
|
138
|
+
socket object only needs a `write` method.
|
139
|
+
|
140
|
+
The driver will emit a `:connect` event when a request is received, and at this
|
141
|
+
point you can detect whether it's a WebSocket and handle it as such. Here's an
|
142
|
+
example using an EventMachine TCP server.
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
module Connection
|
146
|
+
def initialize
|
147
|
+
@driver = WebSocket::Driver.server(self)
|
148
|
+
|
149
|
+
@driver.on :connect, -> (event) do
|
150
|
+
if WebSocket::Driver.websocket?(@driver.env)
|
151
|
+
@driver.start
|
152
|
+
else
|
153
|
+
# handle other HTTP requests
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
@driver.on :message, -> (e) { @driver.text(e.data) }
|
158
|
+
@driver.on :close, -> (e) { close_connection_after_writing }
|
159
|
+
end
|
160
|
+
|
161
|
+
def receive_data(data)
|
162
|
+
@driver.parse(data)
|
163
|
+
end
|
164
|
+
|
165
|
+
def write(data)
|
166
|
+
send_data(data)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
EM.run {
|
171
|
+
EM.start_server('127.0.0.1', 4180, Connection)
|
172
|
+
}
|
173
|
+
```
|
174
|
+
|
175
|
+
In the `:connect` event, `@driver.env` is a Rack env representing the request.
|
176
|
+
If the request has a body, it will be in the `@driver.env['rack.input']` stream,
|
177
|
+
but only as much of the body as you have so far routed to it using the `parse`
|
178
|
+
method.
|
179
|
+
|
180
|
+
|
181
|
+
### Client-side
|
182
|
+
|
183
|
+
Similarly, to implement a WebSocket client you need an object with `url` and
|
184
|
+
`write` methods. Once you have one such object, you ask for a driver for it:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
driver = WebSocket::Driver.client(socket)
|
188
|
+
```
|
189
|
+
|
190
|
+
After this you use the driver API as described below to process incoming data
|
191
|
+
and send outgoing data.
|
192
|
+
|
193
|
+
Client drivers have two additional methods for reading the HTTP data that was
|
194
|
+
sent back by the server:
|
195
|
+
|
196
|
+
- `driver.status` - the integer value of the HTTP status code
|
197
|
+
- `driver.headers` - a hash-like object containing the response headers
|
198
|
+
|
199
|
+
|
200
|
+
### HTTP Proxies
|
201
|
+
|
202
|
+
The client driver supports connections via HTTP proxies using the `CONNECT`
|
203
|
+
method. Instead of sending the WebSocket handshake immediately, it will send a
|
204
|
+
`CONNECT` request, wait for a `200` response, and then proceed as normal.
|
205
|
+
|
206
|
+
To use this feature, call `proxy = driver.proxy(url)` where `url` is the origin
|
207
|
+
of the proxy, including a username and password if required. This produces an
|
208
|
+
object that manages the process of connecting via the proxy. You should call
|
209
|
+
`proxy.start` to begin the connection process, and pass data you receive via the
|
210
|
+
socket to `proxy.parse(data)`. When the proxy emits `:connect`, you should then
|
211
|
+
start sending incoming data to `driver.parse(data)` as normal, and call
|
212
|
+
`driver.start`.
|
213
|
+
|
214
|
+
```rb
|
215
|
+
proxy = driver.proxy('http://username:password@proxy.example.com')
|
216
|
+
|
217
|
+
proxy.on :connect, -> (event) do
|
218
|
+
driver.start
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
The proxy's `:connect` event is also where you should perform a TLS handshake on
|
223
|
+
your TCP stream, if you are connecting to a `wss:` endpoint.
|
224
|
+
|
225
|
+
In the event that proxy connection fails, `proxy` will emit an `:error`. You can
|
226
|
+
inspect the proxy's response via `proxy.status` and `proxy.headers`.
|
227
|
+
|
228
|
+
```rb
|
229
|
+
proxy.on :error, -> (error) do
|
230
|
+
puts error.message
|
231
|
+
puts proxy.status
|
232
|
+
puts proxy.headers.inspect
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
236
|
+
Before calling `proxy.start` you can set custom headers using
|
237
|
+
`proxy.set_header`:
|
238
|
+
|
239
|
+
```rb
|
240
|
+
proxy.set_header('User-Agent', 'ruby')
|
241
|
+
proxy.start
|
242
|
+
```
|
243
|
+
|
244
|
+
|
245
|
+
### Driver API
|
246
|
+
|
247
|
+
Drivers are created using one of the following methods:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
driver = WebSocket::Driver.rack(socket, options)
|
251
|
+
driver = WebSocket::Driver.server(socket, options)
|
252
|
+
driver = WebSocket::Driver.client(socket, options)
|
253
|
+
```
|
254
|
+
|
255
|
+
The `rack` method returns a driver chosen using the socket's `env`. The `server`
|
256
|
+
method returns a driver that will parse an HTTP request and then decide which
|
257
|
+
driver to use for it using the `rack` method. The `client` method always returns
|
258
|
+
a driver for the RFC version of the protocol with masking enabled on outgoing
|
259
|
+
frames.
|
260
|
+
|
261
|
+
The `options` argument is optional, and is a hash. It may contain the following
|
262
|
+
keys:
|
263
|
+
|
264
|
+
- `:max_length` - the maximum allowed size of incoming message frames, in bytes.
|
265
|
+
The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
|
266
|
+
- `:protocols` - an array of strings representing acceptable subprotocols for
|
267
|
+
use over the socket. The driver will negotiate one of these to use via the
|
268
|
+
`Sec-WebSocket-Protocol` header if supported by the other peer.
|
269
|
+
|
270
|
+
All drivers respond to the following API methods, but some of them are no-ops
|
271
|
+
depending on whether the client supports the behaviour.
|
272
|
+
|
273
|
+
Note that most of these methods are commands: if they produce data that should
|
274
|
+
be sent over the socket, they will give this to you by calling
|
275
|
+
`socket.write(string)`.
|
276
|
+
|
277
|
+
#### `driver.on :open, -> (event) { }`
|
278
|
+
|
279
|
+
Adds a callback block to execute when the socket becomes open.
|
280
|
+
|
281
|
+
#### `driver.on :message, -> (event) { }`
|
282
|
+
|
283
|
+
Adds a callback block to execute when a message is received. `event` will have a
|
284
|
+
`data` attribute containing either a string in the case of a text message or an
|
285
|
+
array of integers in the case of a binary message.
|
286
|
+
|
287
|
+
#### `driver.on :error, -> (event) { }`
|
288
|
+
|
289
|
+
Adds a callback to execute when a protocol error occurs due to the other peer
|
290
|
+
sending an invalid byte sequence. `event` will have a `message` attribute
|
291
|
+
describing the error.
|
292
|
+
|
293
|
+
#### `driver.on :close, -> (event) { }`
|
294
|
+
|
295
|
+
Adds a callback block to execute when the socket becomes closed. The `event`
|
296
|
+
object has `code` and `reason` attributes.
|
297
|
+
|
298
|
+
#### `driver.on :ping, -> (event) { }`
|
299
|
+
|
300
|
+
Adds a callback block to execute when a ping is received. You do not need to
|
301
|
+
handle this by sending a pong frame yourself; the driver handles this for you.
|
302
|
+
|
303
|
+
#### `driver.on :pong, -> (event) { }`
|
304
|
+
|
305
|
+
Adds a callback block to execute when a pong is received. If this was in
|
306
|
+
response to a ping you sent, you can also handle this event via the
|
307
|
+
`driver.ping(message) { ... }` callback.
|
308
|
+
|
309
|
+
#### `driver.add_extension(extension)`
|
310
|
+
|
311
|
+
Registers a protocol extension whose operation will be negotiated via the
|
312
|
+
`Sec-WebSocket-Extensions` header. `extension` is any extension compatible with
|
313
|
+
the [websocket-extensions](https://github.com/faye/websocket-extensions-ruby)
|
314
|
+
framework.
|
315
|
+
|
316
|
+
#### `driver.set_header(name, value)`
|
317
|
+
|
318
|
+
Sets a custom header to be sent as part of the handshake response, either from
|
319
|
+
the server or from the client. Must be called before `start`, since this is when
|
320
|
+
the headers are serialized and sent.
|
321
|
+
|
322
|
+
#### `driver.start`
|
323
|
+
|
324
|
+
Initiates the protocol by sending the handshake - either the response for a
|
325
|
+
server-side driver or the request for a client-side one. This should be the
|
326
|
+
first method you invoke. Returns `true` if and only if a handshake was sent.
|
327
|
+
|
328
|
+
#### `driver.parse(string)`
|
329
|
+
|
330
|
+
Takes a string and parses it, potentially resulting in message events being
|
331
|
+
emitted (see `on('message')` above) or in data being sent to `socket.write`.
|
332
|
+
You should send all data you receive via I/O to this method.
|
333
|
+
|
334
|
+
#### `driver.text(string)`
|
335
|
+
|
336
|
+
Sends a text message over the socket. If the socket handshake is not yet
|
337
|
+
complete, the message will be queued until it is. Returns `true` if the message
|
338
|
+
was sent or queued, and `false` if the socket can no longer send messages.
|
339
|
+
|
340
|
+
#### `driver.binary(array)`
|
341
|
+
|
342
|
+
Takes an array of byte-sized integers and sends them as a binary message. Will
|
343
|
+
queue and return `true` or `false` the same way as the `text` method. It will
|
344
|
+
also return `false` if the driver does not support binary messages.
|
345
|
+
|
346
|
+
#### `driver.ping(string = '', &callback)`
|
347
|
+
|
348
|
+
Sends a ping frame over the socket, queueing it if necessary. `string` and the
|
349
|
+
`callback` block are both optional. If a callback is given, it will be invoked
|
350
|
+
when the socket receives a pong frame whose content matches `string`. Returns
|
351
|
+
`false` if frames can no longer be sent, or if the driver does not support
|
352
|
+
ping/pong.
|
353
|
+
|
354
|
+
#### `driver.pong(string = '')`
|
355
|
+
|
356
|
+
Sends a pong frame over the socket, queueing it if necessary. `string` is
|
357
|
+
optional. Returns `false` if frames can no longer be sent, or if the driver does
|
358
|
+
not support ping/pong.
|
359
|
+
|
360
|
+
You don't need to call this when a ping frame is received; pings are replied to
|
361
|
+
automatically by the driver. This method is for sending unsolicited pongs.
|
362
|
+
|
363
|
+
#### `driver.close`
|
364
|
+
|
365
|
+
Initiates the closing handshake if the socket is still open. For drivers with no
|
366
|
+
closing handshake, this will result in the immediate execution of the
|
367
|
+
`on('close')` callback. For drivers with a closing handshake, this sends a
|
368
|
+
closing frame and `emit('close')` will execute when a response is received or a
|
369
|
+
protocol error occurs.
|
370
|
+
|
371
|
+
#### `driver.version`
|
372
|
+
|
373
|
+
Returns the WebSocket version in use as a string. Will either be `hixie-75`,
|
374
|
+
`hixie-76` or `hybi-$version`.
|
375
|
+
|
376
|
+
#### `driver.protocol`
|
377
|
+
|
378
|
+
Returns a string containing the selected subprotocol, if any was agreed upon
|
379
|
+
using the `Sec-WebSocket-Protocol` mechanism. This value becomes available after
|
380
|
+
`emit('open')` has fired.
|