Skip to content

Commit

Permalink
Extract examples to a quick start guide.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Nov 14, 2021
1 parent 0fafda8 commit 33b38ee
Show file tree
Hide file tree
Showing 17 changed files with 261 additions and 244 deletions.
101 changes: 8 additions & 93 deletions docs/intro/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,107 +14,22 @@ websockets requires Python ≥ 3.7.
For each minor version (3.x), only the latest bugfix or security release
(3.x.y) is officially supported.

It doesn't have any dependencies.

Installation
------------

Install websockets with::

pip install websockets

Basic example
-------------

.. _server-example:

Here's a WebSocket server example.

It reads a name from the client, sends a greeting, and closes the connection.

.. literalinclude:: ../../example/server.py
:emphasize-lines: 8,18

.. _client-example:

On the server side, websockets executes the handler coroutine ``hello()`` once
for each WebSocket connection. It closes the connection when the handler
coroutine returns.

Here's a corresponding WebSocket client example.

.. literalinclude:: ../../example/client.py
:emphasize-lines: 10

Using :func:`~client.connect` as an asynchronous context manager ensures the
connection is closed before exiting the ``hello()`` coroutine.

.. _secure-server-example:

Secure example
--------------

Secure WebSocket connections improve confidentiality and also reliability
because they reduce the risk of interference by bad proxies.

The ``wss`` protocol is to ``ws`` what ``https`` is to ``http``. The
connection is encrypted with TLS_ (Transport Layer Security). ``wss``
requires certificates like ``https``.

.. _TLS: https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security

.. admonition:: TLS vs. SSL
:class: tip

TLS is sometimes referred to as SSL (Secure Sockets Layer). SSL was an
earlier encryption protocol; the name stuck.

Here's how to adapt the server example to provide secure connections. See the
documentation of the :mod:`ssl` module for configuring the context securely.

.. literalinclude:: ../../example/secure_server.py
:emphasize-lines: 19-21,24

Here's how to adapt the client.

.. literalinclude:: ../../example/secure_client.py
:emphasize-lines: 10-12,16

This client needs a context because the server uses a self-signed certificate.

A client connecting to a secure WebSocket server with a valid certificate
(i.e. signed by a CA that your Python installation trusts) can simply pass
``ssl=True`` to :func:`~client.connect` instead of building a context.

Browser-based example
---------------------

Here's an example of how to run a WebSocket server and connect from a browser.

Run this script in a console:

.. literalinclude:: ../../example/show_time.py

Then open this HTML file in a browser.

.. literalinclude:: ../../example/show_time.html
:language: html

Synchronization example
-----------------------

A WebSocket server can receive events from clients, process them to update the
application state, and synchronize the resulting state across clients.

Here's an example where any client can increment or decrement a counter.
Updates are propagated to all connected clients.

The concurrency model of :mod:`asyncio` guarantees that updates are
serialized.
Wheels are available for all platforms.

Run this script in a console:
First steps
-----------

.. literalinclude:: ../../example/counter.py
If you're in a hurry, check out these examples.

Then open this HTML file in several browsers.
.. toctree::

.. literalinclude:: ../../example/counter.html
:language: html
quickstart
116 changes: 116 additions & 0 deletions docs/intro/quickstart.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Quick start
===========

.. currentmodule:: websockets

Here are a few examples to get you started quickly with websockets.

Hello world!
------------

Here's a WebSocket server.

It receives a name from the client, sends a greeting, and closes the connection.

.. literalinclude:: ../../example/quickstart/server.py

:func:`~server.serve` executes the connection handler coroutine ``hello()``
once for each WebSocket connection. It closes the WebSocket connection when
the handler returns.

Here's a corresponding WebSocket client.

It sends a name to the server, receives a greeting, and closes the connection.

.. literalinclude:: ../../example/quickstart/client.py

Using :func:`~client.connect` as an asynchronous context manager ensures the
WebSocket connection is closed.

.. _secure-server-example:

Encryption
----------

Secure WebSocket connections improve confidentiality and also reliability
because they reduce the risk of interference by bad proxies.

The ``wss`` protocol is to ``ws`` what ``https`` is to ``http``. The
connection is encrypted with TLS_ (Transport Layer Security). ``wss``
requires certificates like ``https``.

.. _TLS: https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security

.. admonition:: TLS vs. SSL
:class: tip

TLS is sometimes referred to as SSL (Secure Sockets Layer). SSL was an
earlier encryption protocol; the name stuck.

Here's how to adapt the server to encrypt connections. See the documentation
of the :mod:`ssl` module for configuring the context securely.

.. literalinclude:: ../../example/quickstart/server_secure.py

Here's how to adapt the client similarly.

.. literalinclude:: ../../example/quickstart/client_secure.py

This client needs a context because the server uses a self-signed certificate.

When connecting to a secure WebSocket server with a valid certificate — any
certificate signed by a CA that your Python installation trusts — you can
simply pass ``ssl=True`` to :func:`~client.connect`.

In a browser
------------

The WebSocket protocol was invented for the web — as the name says!

Here's how to connect to a WebSocket server in a browser.

Run this script in a console:

.. literalinclude:: ../../example/quickstart/show_time.py

Save this file as ``show_time.html``:

.. literalinclude:: ../../example/quickstart/show_time.html
:language: html

Save this file as ``show_time.js``:

.. literalinclude:: ../../example/quickstart/show_time.js
:language: js

Then open ``show_time.html`` in a browser and see the clock tick irregularly.

Broadcast
---------

A WebSocket server can receive events from clients, process them to update the
application state, and broadcast the updated state to all connected clients.

Here's an example where any client can increment or decrement a counter. The
concurrency model of :mod:`asyncio` guarantees that updates are serialized.

Run this script in a console:

.. literalinclude:: ../../example/quickstart/counter.py

Save this file as ``counter.html``:

.. literalinclude:: ../../example/quickstart/counter.html
:language: html

Save this file as ``counter.css``:

.. literalinclude:: ../../example/quickstart/counter.css
:language: css

Save this file as ``counter.js``:

.. literalinclude:: ../../example/quickstart/counter.js
:language: js

Then open ``counter.html`` file in several browsers and play with [+] and [-].
80 changes: 0 additions & 80 deletions example/counter.html

This file was deleted.

5 changes: 2 additions & 3 deletions example/client.py → example/quickstart/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/env python

# WS client example

import asyncio
import websockets

Expand All @@ -16,4 +14,5 @@ async def hello():
greeting = await websocket.recv()
print(f"<<< {greeting}")

asyncio.run(hello())
if __name__ == "__main__":
asyncio.run(hello())
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/env python

# WSS (WS over TLS) client example, with a self-signed certificate

import asyncio
import pathlib
import ssl
Expand All @@ -22,4 +20,5 @@ async def hello():
greeting = await websocket.recv()
print(f"<<< {greeting}")

asyncio.run(hello())
if __name__ == "__main__":
asyncio.run(hello())
33 changes: 33 additions & 0 deletions example/quickstart/counter.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
body {
font-family: "Courier New", sans-serif;
text-align: center;
}
.buttons {
font-size: 4em;
display: flex;
justify-content: center;
}
.button, .value {
line-height: 1;
padding: 2rem;
margin: 2rem;
border: medium solid;
min-height: 1em;
min-width: 1em;
}
.button {
cursor: pointer;
user-select: none;
}
.minus {
color: red;
}
.plus {
color: green;
}
.value {
min-width: 2em;
}
.state {
font-size: 2em;
}
18 changes: 18 additions & 0 deletions example/quickstart/counter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebSocket demo</title>
<link href="counter.css" rel="stylesheet">
</head>
<body>
<div class="buttons">
<div class="minus button">-</div>
<div class="value">?</div>
<div class="plus button">+</div>
</div>
<div class="state">
<span class="users">?</span> online
</div>
<script src="counter.js"></script>
</body>
</html>
Loading

0 comments on commit 33b38ee

Please sign in to comment.