Skip to content

Commit 61a6a7a

Browse files
committed
Clean up quick start guides.
* Move most examples back to the getting started section. * Add a dedicated howto on encryption. And some drive-by fixes. Refs #1209.
1 parent 82dfd83 commit 61a6a7a

28 files changed

+258
-243
lines changed

docs/deploy/koyeb.rst

-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ or press Ctrl-D to terminate the connection:
139139
< Hello!
140140
Connection closed: 1000 (OK).
141141
142-
143142
You can also confirm that your application shuts down gracefully.
144143

145144
Connect an interactive client again:

docs/howto/encryption.rst

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Encrypt connections
2+
====================
3+
4+
.. currentmodule:: websockets
5+
6+
You should always secure WebSocket connections with TLS_ (Transport Layer
7+
Security).
8+
9+
.. admonition:: TLS vs. SSL
10+
:class: tip
11+
12+
TLS is sometimes referred to as SSL (Secure Sockets Layer). SSL was an
13+
earlier encryption protocol; the name stuck.
14+
15+
The ``wss`` protocol is to ``ws`` what ``https`` is to ``http``.
16+
17+
Secure WebSocket connections require certificates just like HTTPS.
18+
19+
.. _TLS: https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security
20+
21+
.. admonition:: Configure the TLS context securely
22+
:class: attention
23+
24+
The examples below demonstrate the ``ssl`` argument with a TLS certificate
25+
shared between the client and the server. This is a simplistic setup.
26+
27+
Please review the advice and security considerations in the documentation of
28+
the :mod:`ssl` module to configure the TLS context appropriately.
29+
30+
Servers
31+
-------
32+
33+
In a typical :doc:`deployment <../deploy/index>`, the server is behind a reverse
34+
proxy that terminates TLS. The client connects to the reverse proxy with TLS and
35+
the reverse proxy connects to the server without TLS.
36+
37+
In that case, you don't need to configure TLS in websockets.
38+
39+
If needed in your setup, you can terminate TLS in the server.
40+
41+
In the example below, :func:`~asyncio.server.serve` is configured to receive
42+
secure connections. Before running this server, download
43+
:download:`localhost.pem <../../example/tls/localhost.pem>` and save it in the
44+
same directory as ``server.py``.
45+
46+
.. literalinclude:: ../../example/tls/server.py
47+
:caption: server.py
48+
49+
Receive both plain and TLS connections on the same port isn't supported.
50+
51+
Clients
52+
-------
53+
54+
:func:`~asyncio.client.connect` enables TLS automatically when connecting to a
55+
``wss://...`` URI.
56+
57+
This works out of the box when the TLS certificate of the server is valid,
58+
meaning it's signed by a certificate authority that your Python installation
59+
trusts.
60+
61+
In the example above, since the server uses a self-signed certificate, the
62+
client needs to be configured to trust the certificate. Here's how to do so.
63+
64+
.. literalinclude:: ../../example/tls/client.py
65+
:caption: client.py

docs/howto/index.rst

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
How-to guides
22
=============
33

4-
In a hurry? Check out these examples.
4+
Set up your development environment comfortably.
55

66
.. toctree::
77

8-
quickstart
9-
debugging
108
autoreload
9+
debugging
10+
11+
Configure websockets securely in production.
12+
13+
.. toctree::
14+
15+
encryption
1116

1217
If you're stuck, perhaps you'll find the answer here.
1318

@@ -25,7 +30,6 @@ Upgrading from the legacy :mod:`asyncio` implementation to the new one?
2530
Read this.
2631

2732
.. toctree::
28-
:maxdepth: 2
2933

3034
upgrade
3135

docs/howto/quickstart.rst

-170
This file was deleted.

docs/intro/examples.rst

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
Quick examples
2+
==============
3+
4+
.. currentmodule:: websockets
5+
6+
Start a server
7+
--------------
8+
9+
This WebSocket server receives a name from the client, sends a greeting, and
10+
closes the connection.
11+
12+
.. literalinclude:: ../../example/quick/server.py
13+
:caption: server.py
14+
:language: python
15+
16+
:func:`~asyncio.server.serve` executes the connection handler coroutine
17+
``hello()`` once for each WebSocket connection. It closes the WebSocket
18+
connection when the handler returns.
19+
20+
Connect a client
21+
----------------
22+
23+
This WebSocket client sends a name to the server, receives a greeting, and
24+
closes the connection.
25+
26+
.. literalinclude:: ../../example/quick/client.py
27+
:caption: client.py
28+
:language: python
29+
30+
Using :func:`~sync.client.connect` as a context manager ensures that the
31+
WebSocket connection is closed.
32+
33+
Connect a browser
34+
-----------------
35+
36+
The WebSocket protocol was invented for the web — as the name says!
37+
38+
Here's how to connect a browser to a WebSocket server.
39+
40+
Run this script in a console:
41+
42+
.. literalinclude:: ../../example/quick/show_time.py
43+
:caption: show_time.py
44+
:language: python
45+
46+
Save this file as ``show_time.html``:
47+
48+
.. literalinclude:: ../../example/quick/show_time.html
49+
:caption: show_time.html
50+
:language: html
51+
52+
Save this file as ``show_time.js``:
53+
54+
.. literalinclude:: ../../example/quick/show_time.js
55+
:caption: show_time.js
56+
:language: js
57+
58+
Then, open ``show_time.html`` in several browsers or tabs. Clocks tick
59+
irregularly.
60+
61+
Broadcast messages
62+
------------------
63+
64+
Let's send the same timestamps to everyone instead of generating independent
65+
sequences for each connection.
66+
67+
Stop the previous script if it's still running and run this script in a console:
68+
69+
.. literalinclude:: ../../example/quick/sync_time.py
70+
:caption: sync_time.py
71+
:language: python
72+
73+
Refresh ``show_time.html`` in all browsers or tabs. Clocks tick in sync.
74+
75+
Manage application state
76+
------------------------
77+
78+
A WebSocket server can receive events from clients, process them to update the
79+
application state, and broadcast the updated state to all connected clients.
80+
81+
Here's an example where any client can increment or decrement a counter. The
82+
concurrency model of :mod:`asyncio` guarantees that updates are serialized.
83+
84+
This example keep tracks of connected users explicitly in ``USERS`` instead of
85+
relying on :attr:`server.connections <asyncio.server.Server.connections>`. The
86+
result is the same.
87+
88+
Run this script in a console:
89+
90+
.. literalinclude:: ../../example/quick/counter.py
91+
:caption: counter.py
92+
:language: python
93+
94+
Save this file as ``counter.html``:
95+
96+
.. literalinclude:: ../../example/quick/counter.html
97+
:caption: counter.html
98+
:language: html
99+
100+
Save this file as ``counter.css``:
101+
102+
.. literalinclude:: ../../example/quick/counter.css
103+
:caption: counter.css
104+
:language: css
105+
106+
Save this file as ``counter.js``:
107+
108+
.. literalinclude:: ../../example/quick/counter.js
109+
:caption: counter.js
110+
:language: js
111+
112+
Then open ``counter.html`` file in several browsers and play with [+] and [-].

0 commit comments

Comments
 (0)