mirror of
https://github.com/django/daphne.git
synced 2025-04-21 01:02:06 +03:00
Update backends docs, remove old message standards
This commit is contained in:
parent
d452486524
commit
3dec8e09b3
|
@ -6,18 +6,6 @@ Draft ASGI Spec
|
|||
considered draft yet. Even the name might change; this is being written
|
||||
as development progresses.**
|
||||
|
||||
::
|
||||
|
||||
PEP: XXX
|
||||
Title: ASGI (Asynchronous Server Gateway Interface)
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Andrew Godwin <andrew@aeracode.org>
|
||||
Status: Draft
|
||||
Type: Informational
|
||||
Content-Type: text/x-rst
|
||||
Created: ?
|
||||
Post-History: ?
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
|
|
@ -1,28 +1,34 @@
|
|||
Backends
|
||||
========
|
||||
Channel Layer Types
|
||||
===================
|
||||
|
||||
Multiple choices of backend are available, to fill different tradeoffs of
|
||||
complexity, throughput and scalability. You can also write your own backend if
|
||||
you wish; the API is very simple and documented below.
|
||||
you wish; the spec they confirm to is called :doc:`ASGI <asgi>`. Any
|
||||
ASGI-compliant channel layer can be used.
|
||||
|
||||
Redis
|
||||
-----
|
||||
|
||||
The Redis backend is the recommended backend to run Channels with, as it
|
||||
The Redis layer is the recommended backend to run Channels with, as it
|
||||
supports both high throughput on a single Redis server as well as the ability
|
||||
to run against a set of Redis servers in a sharded mode.
|
||||
|
||||
To use the Redis backend you have to install the redis package::
|
||||
To use the Redis layer, simply install it from PyPI (it lives in a separate
|
||||
package, as we didn't want to force a dependency on the redis-py for the main
|
||||
install):
|
||||
|
||||
pip install -U redis
|
||||
pip install -U asgi_redis
|
||||
|
||||
By default, it will attempt to connect to a Redis server on ``localhost:6379``,
|
||||
but you can override this with the ``HOSTS`` setting::
|
||||
but you can override this with the ``hosts`` key in its config::
|
||||
|
||||
CHANNEL_BACKENDS = {
|
||||
CHANNEL_LAYERS = {
|
||||
"default": {
|
||||
"BACKEND": "channels.backends.redis_py.RedisChannelBackend",
|
||||
"HOSTS": [("redis-channel-1", 6379), ("redis-channel-2", 6379)],
|
||||
"BACKEND": "asgi_redis.RedisChannelLayer",
|
||||
"ROUTING": "???",
|
||||
"CONFIG": {
|
||||
"hosts": [("redis-channel-1", 6379), ("redis-channel-2", 6379)],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -49,72 +55,38 @@ settings. Any misconfigured interface server or worker will drop some or all
|
|||
messages.
|
||||
|
||||
|
||||
In-memory
|
||||
---------
|
||||
|
||||
The in-memory backend is the simplest, and not really a backend as such;
|
||||
it exists purely to enable Django to run in a "normal" mode where no Channels
|
||||
functionality is available, just normal HTTP request processing. You should
|
||||
never need to set it explicitly.
|
||||
|
||||
This backend provides no network transparency or non-blocking guarantees.
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
=======
|
||||
Writing Custom Backends
|
||||
-----------------------
|
||||
The database layer is intended as a short-term solution for people who can't
|
||||
use a more production-ready layer (for example, Redis), but still want something
|
||||
that will work cross-process. It has poor performance, and is only
|
||||
recommended for development or extremely small deployments.
|
||||
|
||||
Backend Requirements
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
This layer is included with Channels; just set your ``BACKEND`` to
|
||||
``channels.backends.database.DatabaseChannelLayer``, and it will use the
|
||||
default Django database alias to store messages. You can change the alias
|
||||
by setting ``CONFIG`` to ``{'alias': 'aliasname'}``.
|
||||
|
||||
While the channel backends are pluggable, there's a minimum standard they
|
||||
must meet in terms of the way they perform.
|
||||
|
||||
In particular, a channel backend MUST:
|
||||
In-memory
|
||||
---------
|
||||
|
||||
* Provide a ``send()`` method which sends a message onto a named channel
|
||||
The in-memory layer is purely an implementation detail used when running
|
||||
the entire Django stack in a single process; the most common case of this
|
||||
is ``runserver``, where a server thread, channel layer, and worker thread all
|
||||
co-exist inside the same python process.
|
||||
|
||||
* Provide a ``receive_many()`` method which returns an available message on the
|
||||
provided channels, or returns no message either instantly or after a short
|
||||
delay (it must not block indefinitely)
|
||||
You should not need to use this process manually, but if you want to,
|
||||
it's available from ``asgiref.inmemory.ChannelLayer``.
|
||||
|
||||
* Provide a ``group_add()`` method which adds a channel to a named group
|
||||
for at least the provided expiry period.
|
||||
|
||||
* Provide a ``group_discard()`` method with removes a channel from a named
|
||||
group if it was added, and nothing otherwise.
|
||||
Writing Custom Channel Layers
|
||||
-----------------------------
|
||||
|
||||
* Provide a ``group_members()`` method which returns an iterable of all
|
||||
channels currently in the group.
|
||||
|
||||
* Preserve the ordering of messages inside a channel
|
||||
|
||||
* Never deliver a message more than once (design for at-most-once delivery)
|
||||
|
||||
* Never block on sending of a message (dropping the message/erroring is preferable to blocking)
|
||||
|
||||
* Be able to store messages of at least 5MB in size
|
||||
|
||||
* Allow for channel and group names of up to 200 printable ASCII characters
|
||||
|
||||
* Expire messages only after the expiry period provided is up (a backend may
|
||||
keep them longer if it wishes, but should expire them at some reasonable
|
||||
point to ensure users do not come to rely on permanent messages)
|
||||
|
||||
In addition, it SHOULD:
|
||||
|
||||
* Provide a ``receive_many_blocking()`` method which is like ``receive_many()``
|
||||
but blocks until a message is available.
|
||||
|
||||
* Provide a ``send_group()`` method which sends a message to every channel
|
||||
in a group.
|
||||
|
||||
* Make ``send_group()`` perform better than ``O(n)``, where ``n`` is the
|
||||
number of members in the group; preferably send the messages to all
|
||||
members in a single call to your backing datastore or protocol.
|
||||
|
||||
* Try and preserve a rough global ordering, so that one busy channel does not
|
||||
drown out an old message in another channel if a worker is listening on both.
|
||||
The interface channel layers present to Django and other software that
|
||||
communicates over them is codified in a specification called :doc:`ASGI <asgi>`.
|
||||
|
||||
Any channel layer that conforms to the :doc:`ASGI spec <asgi>` can be used
|
||||
by Django; just set ``BACKEND`` to the class to instantiate and ``CONFIG`` to
|
||||
a dict of keyword arguments to initialize the class with.
|
||||
|
|
|
@ -27,7 +27,6 @@ Contents:
|
|||
getting-started
|
||||
deploying
|
||||
integration-changes
|
||||
message-standards
|
||||
scaling
|
||||
backends
|
||||
integration-plan
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
Message Standards
|
||||
=================
|
||||
|
||||
Some standardised message formats are used for common message types - they
|
||||
are detailed below. Message formats are meant to be generic and offload as
|
||||
much protocol-specific processing to the interface server as is reasonable;
|
||||
thus, they should generally represent things at as high a level as makes sense.
|
||||
|
||||
In addition to the standards outlined below, each message may contain a
|
||||
``reply_channel``, which details where to send responses. Protocols with
|
||||
separate connection and data receiving messages (like WebSockets) will only
|
||||
contain the connection and detailed client information in the first message;
|
||||
use the ``@channel_session`` decorator to persist this data to consumers of
|
||||
the received data (or something else based on ``reply_channel``).
|
||||
|
||||
All messages must be able to be encoded as JSON; channel backends don't
|
||||
necessarily have to use JSON, but we consider it the lowest common denominator
|
||||
for serialisation format compatibility.
|
||||
|
||||
The size limit on messages is 1MB (while channel backends may support larger
|
||||
sizes, all message formats should stay under this limit, which might include
|
||||
multi-part messages where large content must be transferred).
|
||||
|
||||
The length limit on channel names is 200 printable ASCII characters.
|
||||
|
||||
|
||||
HTTP Request
|
||||
------------
|
||||
|
||||
Represents a full-fledged, single HTTP request coming in from a client.
|
||||
|
||||
Standard channel name is ``http.request``.
|
||||
|
||||
Contains the following keys:
|
||||
|
||||
* get: Dict of {key: [value, ...]} of GET variables (keys and values are strings)
|
||||
* post: Dict of {key: [value, ...]} of POST variables (keys and values are strings)
|
||||
* cookies: Dict of cookies as {cookie_name: cookie_value} (names and values are strings)
|
||||
* headers: Dict of {header name: value}. Multiple headers of the same name are concatenated into one value separated by commas.
|
||||
* meta: Dict of HTTP headers and info as defined in the Django Request docs (names and values are strings)
|
||||
* path: String, full path to the requested page, without query string or domain
|
||||
* root_path: Path designated as the "root" of the application (SCRIPT_NAME)
|
||||
* method: String, upper-cased HTTP method
|
||||
* server: [host, port] showing the address the client connected to
|
||||
* client: [host, port] of the remote client
|
||||
|
||||
Should come with an associated ``reply_channel`` which accepts HTTP Responses.
|
||||
|
||||
|
||||
HTTP Response
|
||||
-------------
|
||||
|
||||
Sends either a part of a response or a whole response to a HTTP client - to do
|
||||
streaming responses, several response messages are sent with ``more_content: True``
|
||||
and the final one has the key omitted. Normal, single-shot responses do not
|
||||
need the key at all.
|
||||
|
||||
Due to the 1MB size limit on messages, some larger responses will have to be
|
||||
sent multi-part to stay within the limit.
|
||||
|
||||
Only sent on reply channels.
|
||||
|
||||
Keys that must only be in the first message of a set:
|
||||
|
||||
* content_type: String, mimetype of content
|
||||
* status: Integer, numerical HTTP status code
|
||||
* cookies: List of cookies to set (as encoded cookie strings suitable for headers)
|
||||
* headers: Dictionary of headers (key is header name, value is value, both strings)
|
||||
|
||||
All messages in a set can the following keys:
|
||||
|
||||
* content: String of content to send
|
||||
* more_content: Boolean, signals the interface server should wait for another response chunk to stream.
|
||||
|
||||
|
||||
HTTP Disconnect
|
||||
---------------
|
||||
|
||||
Send when a client disconnects early, before the response has been sent.
|
||||
Only sent by long-polling-capable HTTP interface servers.
|
||||
|
||||
Standard channel name is ``http.disconnect``.
|
||||
|
||||
Contains no keys.
|
||||
|
||||
|
||||
WebSocket Connection
|
||||
--------------------
|
||||
|
||||
Sent when a new WebSocket is connected.
|
||||
|
||||
Standard channel name is ``websocket.connect``.
|
||||
|
||||
Contains the same keys as HTTP Request, without the ``POST`` or ``method`` keys.
|
||||
|
||||
|
||||
WebSocket Receive
|
||||
-----------------
|
||||
|
||||
Sent when a datagram is received on the WebSocket.
|
||||
|
||||
Standard channel name is ``websocket.receive``.
|
||||
|
||||
Contains the following keys:
|
||||
|
||||
* content: String content of the datagram.
|
||||
* binary: Boolean, saying if the content is binary. If not present or false, content is a UTF8 string.
|
||||
|
||||
|
||||
WebSocket Client Close
|
||||
----------------------
|
||||
|
||||
Sent when the WebSocket is closed by either the client or the server.
|
||||
|
||||
Standard channel name is ``websocket.disconnect``.
|
||||
|
||||
Contains no keys.
|
||||
|
||||
|
||||
WebSocket Send/Close
|
||||
--------------------
|
||||
|
||||
Sent by a Django consumer to send a message back over the WebSocket to
|
||||
the client or close the client connection. The content is optional if close
|
||||
is set, and close will happen after any content is sent, if some is present.
|
||||
|
||||
Only sent on reply channels.
|
||||
|
||||
Contains the keys:
|
||||
|
||||
* content: String content of the datagram.
|
||||
* binary: If the content is to be interpreted as text or binary.
|
||||
* close: Boolean. If set to True, will close the client connection.
|
Loading…
Reference in New Issue
Block a user