Сессии¶
Channels поддерживает стандартные сессии Django с использованием HTTP cookies как для HTTP, так и для WebSocket. Однако здесь есть некоторые оговорки.
Основное использование¶
SessionMiddleware
в Channels поддерживает стандартные сессии Django, и, как и все промежуточное ПО, должен быть обернут вокруг ASGI-приложения, которому нужна информация о сессии в его области действия (например, URLRouter
, чтобы применить его к целой коллекции потребителей или к отдельному потребителю).
Для работы SessionMiddleware
требуется CookieMiddleware
. Для удобства они также представлены в виде комбинированного вызываемого объекта SessionMiddlewareStack
, который включает оба. Все они могут быть импортированы из channels.session
.
Чтобы использовать промежуточное программное обеспечение, оберните его вокруг потребителя соответствующего уровня в вашем asgi.py
:
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.sessions import SessionMiddlewareStack
from myapp import consumers
application = ProtocolTypeRouter({
"websocket": SessionMiddlewareStack(
URLRouter([
url(r"^front(end)/$", consumers.AsyncChatConsumer.as_asgi()),
])
),
})
SessionMiddleware
будет работать только с протоколами, которые предоставляют HTTP-заголовки в своих scope
- по умолчанию это HTTP и WebSocket.
Чтобы получить доступ к сессии, используйте self.scope["session"]
в коде потребителя:
class ChatConsumer(WebsocketConsumer):
def connect(self, event):
self.scope["session"]["seed"] = random.randint(1, 1000)
SessionMiddleware
соблюдает все те же настройки Django, что и стандартный фреймворк сессий Django, как SESSION_COOKIE_NAME
и SESSION_COOKIE_DOMAIN
.
Постоянство сессии¶
В HTTP потребителях или ASGI приложениях сохранение сессий работает так, как вы ожидаете от HTTP представлений Django - сессии сохраняются всякий раз, когда вы отправляете HTTP ответ, не имеющий статусного кода 500
.
Это делается путем переопределения всех сообщений http.response.start
для вставки заголовков cookie в ответ при его отправке. Если вы установили параметр SESSION_SAVE_EVERY_REQUEST
в значение True
, он будет сохранять сессию и отправлять cookie при каждом ответе, в противном случае он будет сохранять только при каждом изменении сессии.
Однако если вы находитесь в WebSocket-потребителе, сессия заполняется но никогда не сохраняется автоматически - вы должны сами вызывать scope["session"].save()
всякий раз, когда хотите сохранить сессию в своем хранилище сессий. Если вы не сохраните сессию, она будет корректно работать внутри потребителя (поскольку хранится как переменная экземпляра), но другие соединения или HTTP представления не смогут увидеть изменения.
Примечание
Если вы работаете с HTTP-потребителем, выполняющим длительный опрос, вы можете захотеть сохранить изменения в сессии перед отправкой ответа. Если вы хотите сделать это, вызовите scope["session"].save()
.