Skip to content

Commit 58b506e

Browse files
committed
Clean up docs
1 parent 5d9304c commit 58b506e

File tree

2 files changed

+105
-81
lines changed

2 files changed

+105
-81
lines changed

lib/mint/web_socket.ex

Lines changed: 104 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,14 @@ defmodule Mint.WebSocket do
115115
import Mint.HTTP, only: [get_private: 2, put_private: 3, protocol: 1]
116116

117117
@typedoc """
118-
An immutable data structure representing a WebSocket connection
118+
An immutable data structure representing WebSocket state.
119+
120+
You will usually want to keep these around:
121+
122+
* The Mint connection
123+
* The request reference for the WebSocket upgrade request
124+
* This WebSocket data structure
125+
119126
"""
120127
@opaque t :: %__MODULE__{
121128
extensions: [Extension.t()],
@@ -131,55 +138,52 @@ defmodule Mint.WebSocket do
131138
@type error :: Mint.Types.error() | WebSocketError.t() | UpgradeFailureError.t()
132139

133140
@typedoc """
134-
Shorthand notations for control frames
141+
Shorthand notations for control frames.
135142
136-
* `:ping` - shorthand for `{:ping, ""}`
137-
* `:pong` - shorthand for `{:pong, ""}`
138-
* `:close` - shorthand for `{:close, nil, nil}`
143+
* `:ping` - shorthand for `{:ping, ""}`
144+
* `:pong` - shorthand for `{:pong, ""}`
145+
* `:close` - shorthand for `{:close, nil, nil}`
139146
140147
These may be passed to `encode/2`. Frames decoded with `decode/2` are always
141148
in `t:frame/0` format.
142149
"""
143150
@type shorthand_frame :: :ping | :pong | :close
144151

145152
@typedoc """
146-
A WebSocket frame
147-
148-
* `{:binary, binary}` - a frame containing binary data. Binary frames
149-
can be used to send arbitrary binary data such as a PDF.
150-
* `{:text, text}` - a frame containing string data. Text frames must be
151-
valid utf8. Elixir has wonderful support for utf8: `String.valid?/1`
152-
can detect valid and invalid utf8.
153-
* `{:ping, binary}` - a control frame which the server should respond to
154-
with a pong. The binary data must be echoed in the pong response.
155-
* `{:pong, binary}` - a control frame which forms a reply to a ping frame.
156-
Pings and pongs may be used to check the a connection is alive or to
157-
estimate latency.
158-
* `{:close, code, reason}` - a control frame used to request that a connection
159-
be closed or to acknowledgee a close frame send by the server.
153+
A WebSocket frame.
154+
155+
* `{:binary, binary}` - a frame containing binary data. Binary frames
156+
can be used to send arbitrary binary data such as a PDF.
157+
* `{:text, text}` - a frame containing string data. Text frames must be
158+
valid utf8. Elixir has wonderful support for utf8: `String.valid?/1`
159+
can detect valid and invalid utf8.
160+
* `{:ping, binary}` - a control frame which the server should respond to
161+
with a pong. The binary data must be echoed in the pong response.
162+
* `{:pong, binary}` - a control frame which forms a reply to a ping frame.
163+
Pings and pongs may be used to check the a connection is alive or to
164+
estimate latency.
165+
* `{:close, code, reason}` - a control frame used to request that a connection
166+
be closed or to acknowledgee a close frame send by the server.
160167
161168
These may be passed to `encode/2` or returned from `decode/2`.
162169
163170
## Close frames
164171
165172
In order to close a WebSocket connection gracefully, either the client or
166173
server sends a close frame. Then the other endpoint responds with a
167-
close with code `1_000` and then closes the TCP connection. This can be
168-
accomplished in Mint.WebSocket like so:
174+
close with code `1_000` and then closes the TCP/TLS connection. This can be
175+
accomplished in `Mint.WebSocket` like so:
169176
170-
```elixir
171-
{:ok, websocket, data} = Mint.WebSocket.encode(websocket, :close)
172-
{:ok, conn} = Mint.WebSocket.stream_request_body(conn, ref, data)
177+
{:ok, websocket, data} = Mint.WebSocket.encode(websocket, :close)
178+
{:ok, conn} = Mint.WebSocket.stream_request_body(conn, ref, data)
173179
174-
close_response = receive(do: (message -> message))
175-
{:ok, conn, [{:data, ^ref, data}]} = Mint.WebSocket.stream(conn, close_response)
176-
{:ok, websocket, [{:close, 1_000, ""}]} = Mint.WebSocket.decode(websocket, data)
180+
close_response = receive(do: (message -> message))
181+
{:ok, conn, [{:data, ^ref, data}]} = Mint.WebSocket.stream(conn, close_response)
182+
{:ok, websocket, [{:close, 1_000, ""}]} = Mint.WebSocket.decode(websocket, data)
177183
178-
Mint.HTTP.close(conn)
179-
```
184+
Mint.HTTP.close(conn)
180185
181-
[rfc6455
182-
section 7.4.1](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1)
186+
[RFC6455 § 7.4.1](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1)
183187
documents codes which may be used in the `code` element.
184188
"""
185189
@type frame ::
@@ -206,8 +210,8 @@ defmodule Mint.WebSocket do
206210
207211
## Options
208212
209-
* `:extensions` - a list of extensions to negotiate. See the extensions
210-
section below.
213+
* `:extensions` - a list of extensions to negotiate. See the extensions
214+
section below.
211215
212216
## Extensions
213217
@@ -220,27 +224,33 @@ defmodule Mint.WebSocket do
220224
Extensions may be passed as a list of `Mint.WebSocket.Extension` structs
221225
or with the following shorthand notations:
222226
223-
* `module` - shorthand for `{module, []}`
224-
* `{module, params}` - shorthand for `{module, params, []}`
225-
* `{module, params, opts}` - a shorthand which is expanded to a
226-
`Mint.WebSocket.Extension` struct
227+
* `module` - shorthand for `{module, []}`
228+
* `{module, params}` - shorthand for `{module, params, []}`
229+
* `{module, params, opts}` - a shorthand which is expanded to a
230+
`Mint.WebSocket.Extension` struct
227231
228232
## Examples
229233
230-
```elixir
231-
{:ok, conn} = Mint.HTTP.connect(:http, "localhost", 9_000)
232-
{:ok, conn, ref} =
233-
Mint.WebSocket.upgrade(:ws, conn, "/", [], extensions: [Mint.WebSocket.PerMessageDeflate])
234-
# or provide params:
235-
{:ok, conn, ref} =
236-
Mint.WebSocket.upgrade(
237-
:ws,
238-
conn,
239-
"/",
240-
[],
241-
extensions: [{Mint.WebSocket.PerMessageDeflate, [:client_max_window_bits]]}]
242-
)
243-
```
234+
First, establish the Mint connection:
235+
236+
{:ok, conn} = Mint.HTTP.connect(:http, "localhost", 9_000)
237+
238+
Then, send the upgrade request (with an extension in this example):
239+
240+
{:ok, conn, ref} =
241+
Mint.WebSocket.upgrade(:ws, conn, "/", [], extensions: [Mint.WebSocket.PerMessageDeflate])
242+
243+
Here's an example of providing extension parameters:
244+
245+
{:ok, conn, ref} =
246+
Mint.WebSocket.upgrade(
247+
:ws,
248+
conn,
249+
"/",
250+
[],
251+
extensions: [{Mint.WebSocket.PerMessageDeflate, [:client_max_window_bits]]}]
252+
)
253+
244254
"""
245255
@spec upgrade(
246256
scheme :: :ws | :wss,
@@ -291,30 +301,36 @@ defmodule Mint.WebSocket do
291301

292302
@doc """
293303
Creates a new WebSocket data structure given the server's reply to the
294-
upgrade request
304+
upgrade request.
305+
306+
`request_ref` should be the reference of the request made with `upgrade/5`.
307+
`status` and `response_headers` should be the status code and headers
308+
of the server's response to the upgrade request—see the example below.
309+
310+
The returned [WebSocket data structure](`t:t/0`) is used to encode and decode frames.
295311
296312
This function will setup any extensions accepted by the server using
297313
the `c:Mint.WebSocket.Extension.init/2` callback.
298314
299315
## Options
300316
301-
* `:mode` - (default: `:active`) either `:active` or `:passive`. This
302-
corresponds to the same option in `Mint.HTTP.connect/4`.
317+
* `:mode` - (default: `:active`) either `:active` or `:passive`. This
318+
corresponds to the same option in `Mint.HTTP.connect/4`.
303319
304320
## Examples
305321
306-
```elixir
307-
http_reply = receive(do: (message -> message))
308-
{:ok, conn, [{:status, ^ref, status}, {:headers, ^ref, headers}, {:done, ^ref}]} =
309-
Mint.WebSocket.stream(conn, http_reply)
322+
http_reply = receive(do: (message -> message))
323+
324+
{:ok, conn, [{:status, ^ref, status}, {:headers, ^ref, headers}, {:done, ^ref}]} =
325+
Mint.WebSocket.stream(conn, http_reply)
326+
327+
{:ok, conn, websocket} =
328+
Mint.WebSocket.new(conn, ref, status, headers)
310329
311-
{:ok, conn, websocket} =
312-
Mint.WebSocket.new(conn, ref, status, resp_headers)
313-
```
314330
"""
315331
@spec new(
316332
Mint.HTTP.t(),
317-
reference(),
333+
Mint.Types.request_ref(),
318334
Mint.Types.status(),
319335
Mint.Types.headers()
320336
) ::
@@ -360,23 +376,26 @@ defmodule Mint.WebSocket do
360376

361377
@doc """
362378
A wrapper around `Mint.HTTP.stream/2` for streaming HTTP and WebSocket
363-
messages
379+
messages.
364380
365-
This function does not decode WebSocket frames. Instead, once a WebSocket
381+
**This function does not decode WebSocket frames**. Instead, once a WebSocket
366382
connection has been established, decode any `{:data, request_ref, data}`
367383
frames with `decode/2`.
368384
369-
This function is a drop-in replacement for `Mint.HTTP.stream/2` which
385+
This function is a drop-in replacement for `Mint.HTTP.stream/2`, which
370386
enables streaming WebSocket data after the bootstrapping HTTP/1 connection
371387
has concluded. It decodes both WebSocket and regular HTTP messages.
372388
373389
## Examples
374390
375391
message = receive(do: (message -> message))
392+
376393
{:ok, conn, [{:data, ^websocket_ref, data}]} =
377394
Mint.WebSocket.stream(conn, message)
395+
378396
{:ok, websocket, [{:text, "hello world!"}]} =
379397
Mint.WebSocket.decode(websocket, data)
398+
380399
"""
381400
@spec stream(Mint.HTTP.t(), term()) ::
382401
{:ok, Mint.HTTP.t(), [Mint.Types.response()]}
@@ -419,7 +438,7 @@ defmodule Mint.WebSocket do
419438
end
420439

421440
@doc """
422-
Receives data from the socket
441+
Receives data from the socket.
423442
424443
This function is used instead of `stream/2` when the connection is
425444
in `:passive` mode. You must pass the `mode: :passive` option to
@@ -431,8 +450,10 @@ defmodule Mint.WebSocket do
431450
## Examples
432451
433452
{:ok, conn, [{:data, ^ref, data}]} = Mint.WebSocket.recv(conn, 0, 5_000)
453+
434454
{:ok, websocket, [{:text, "hello world!"}]} =
435455
Mint.WebSocket.decode(websocket, data)
456+
436457
"""
437458
@spec recv(Mint.HTTP.t(), non_neg_integer(), timeout()) ::
438459
{:ok, Mint.HTTP.t(), [Mint.Types.response()]}
@@ -460,12 +481,17 @@ defmodule Mint.WebSocket do
460481
end
461482

462483
@doc """
463-
Streams chunks of data on the connection
484+
Streams chunks of data on the connection.
464485
465486
`stream_request_body/3` should be used to send encoded data on an
466487
established WebSocket connection that has already been upgraded with
467488
`upgrade/5`.
468489
490+
> #### Encoding {: .warning}
491+
>
492+
> This function doesn't perform any encoding. You should use `encode/2`
493+
> to encode frames before sending them with `stream_request_body/3`.
494+
469495
This function is a wrapper around `Mint.HTTP.stream_request_body/3`. It
470496
delegates to that function unless the `request_ref` belongs to an HTTP/1
471497
WebSocket connection. When the request is an HTTP/1 WebSocket, this
@@ -479,6 +505,7 @@ defmodule Mint.WebSocket do
479505
480506
{:ok, websocket, data} = Mint.WebSocket.encode(websocket, {:text, "hello world!"})
481507
{:ok, conn} = Mint.WebSocket.stream_request_body(conn, websocket_ref, data)
508+
482509
"""
483510
@spec stream_request_body(
484511
Mint.HTTP.t(),
@@ -505,7 +532,7 @@ defmodule Mint.WebSocket do
505532
end
506533

507534
@doc """
508-
Encodes a frame into a binary
535+
Encodes a frame into a binary.
509536
510537
The resulting binary may be sent with `stream_request_body/3`.
511538
@@ -514,29 +541,27 @@ defmodule Mint.WebSocket do
514541
515542
## Examples
516543
517-
```elixir
518-
{:ok, websocket, data} = Mint.WebSocket.encode(websocket, {:text, "hello world"})
519-
{:ok, conn} = Mint.WebSocket.stream_request_body(conn, websocket_ref, data)
520-
```
544+
{:ok, websocket, data} = Mint.WebSocket.encode(websocket, {:text, "hello world"})
545+
{:ok, conn} = Mint.WebSocket.stream_request_body(conn, websocket_ref, data)
546+
521547
"""
522548
@spec encode(t(), shorthand_frame() | frame()) :: {:ok, t(), binary()} | {:error, t(), any()}
523549
defdelegate encode(websocket, frame), to: Frame
524550

525551
@doc """
526-
Decodes a binary into a list of frames
552+
Decodes a binary into a list of frames.
527553
528-
The binary may received from the connection with `Mint.HTTP.stream/2`.
554+
The binary may received from the connection with `stream/2`.
529555
530556
This function will invoke the `c:Mint.WebSocket.Extension.decode/2` callback
531557
for any accepted extensions.
532558
533559
## Examples
534560
535-
```elixir
536-
message = receive(do: (message -> message))
537-
{:ok, conn, [{:data, ^ref, data}]} = Mint.HTTP.stream(conn, message)
538-
{:ok, websocket, frames} = Mint.WebSocket.decode(websocket, data)
539-
```
561+
message = receive(do: (message -> message))
562+
{:ok, conn, [{:data, ^ref, data}]} = Mint.HTTP.stream(conn, message)
563+
{:ok, websocket, frames} = Mint.WebSocket.decode(websocket, data)
564+
540565
"""
541566
@spec decode(t(), data :: binary()) ::
542567
{:ok, t(), [frame() | {:error, term()}]} | {:error, t(), any()}

lib/mint/web_socket/extension.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ defmodule Mint.WebSocket.Extension do
1111
reference when writing future extensions, but future extensions should be
1212
written as separate libraries which extend `Mint.WebSocket` instead of
1313
built-in. Also note that extensions must operate on the internal
14-
representations of frames using the records defined in `Mint.WebSocket.Frame`,
15-
which are not documented.
14+
representations of frames using the records defined in an internal module.
1615
"""
1716

1817
alias Mint.WebSocketError

0 commit comments

Comments
 (0)