Я автор django-websocket. Я не настоящий эксперт в области веб-сокетов и сетей, однако я думаю, что у меня есть приличное понимание того, что происходит. Извините, что углубился в детали. Даже если большая часть ответа не относится к вашему вопросу, это может помочь вам в какой-то другой момент. : -)
Как работают веб-сокеты
Позвольте мне кратко объяснить, что такое веб-розетка. Websocket начинается как нечто, что действительно выглядит как простой HTTP-запрос, установленный из браузера. Через заголовок HTTP он указывает, что он хочет «обновить» протокол, чтобы он стал веб-сокетом, а не HTTP-запросом. Если сервер поддерживает веб-сокеты, он соглашается на квитирование, и оба - сервер и клиент - теперь знают, что они будут использовать установленный сокет TCP, который ранее использовался для HTTP-запроса, в качестве соединения для обмена сообщениями веб-сокетов.
Помимо отправки и ожидания сообщений, они, конечно же, имеют возможность закрыть соединение в любое время.
Как django-websocket использует среду запросов Python для wsgi, чтобы захватить сокет
Теперь давайте углубимся в детали того, как django-websocket реализует «обновление» HTTP-запроса в цикле запроса-ответа django.
Django обычно использует спецификацию WSGI для общения с веб-сервером, таким как apache, gunicorn и т. Д. Эта спецификация была разработана только с учетом очень ограниченной модели обмена данными HTTP. Предполагается, что он получает HTTP-запрос (только входящие данные) и возвращает ответ (только исходящие данные). Из-за этого сложно внедрить django в концепцию веб-сокета, где разрешено двунаправленное общение.
Что я делаю в django-websocket, чтобы добиться этого, так это то, что я очень глубоко копаюсь во внутренностях WSGI и объекте запроса django, чтобы получить нижележащий сокет. Этот сокет tcp затем используется для непосредственной обработки запроса HTTP до экземпляра websocket.
Теперь к вашему первоначальному вопросу ...
Надеюсь, из вышесказанного становится очевидным, что при установке веб-сокета возвращать HttpResponse бессмысленно. Вот почему вы обычно ничего не возвращаете в представлении, которое обрабатывается django-websocket.
Однако я хотел придерживаться концепции представления, которое содержит логику и возвращает данные на основе входных данных. Вот почему вы должны использовать только код в вашем представлении для обработки веб-сокета.
После возврата из представления веб-розетка автоматически закрывается. Это сделано по причине: мы не хотим держать сокет открытым в течение неопределенного периода времени и надеемся, что клиент (браузер) закроет его.
Вот почему вы не можете получить доступ к веб-сокету с помощью django-websocket за пределами вашего обзора. Дескриптор файла тогда, конечно, устанавливается в -1, указывая, что он уже закрыт.
Отказ от ответственности
Я объяснил выше, что копаюсь в окружающей среде django, чтобы каким-то образом - очень хакерским способом - получить доступ к нижележащему сокету. Это очень хрупко и также не должно работать, поскольку WSGI не предназначен для этого! Я также объяснил выше, что веб-сокет закрывается после завершения представления - однако после закрытия веб-сокета (И закрыл сокет tcp) реализация WSGI django пытается отправить HTTP-ответ - он не знает о веб-сокетах и думает, что нормальный цикл запроса-ответа HTTP. Но сокет уже закрыт и отправка не удастся. Это обычно вызывает исключение в django.
Это не повлияло на мои тесты с сервером разработки. Браузер никогда не заметит (вы знаете ... сокет уже закрыт ;-) - но возникновение необработанной ошибки в каждом запросе не очень хорошая концепция и может привести к утечке памяти, неправильно обрабатывает отключение соединения с базой данных и многие другие неприятные вещи что будет сломаться в какой-то момент, если вы используете django-websocket не только для экспериментов.
Вот почему я бы действительно советовал вам пока не использовать веб-сокеты с django .Это не работает по дизайну.Django и особенно WSGI потребуется полный пересмотр для решения этих проблем (см. это обсуждение для веб-сокетов и WSGI ).С тех пор я бы предложил использовать что-то вроде eventlet .Eventlet имеет работающую реализацию websocket (я позаимствовал некоторый код из eventlet для начальной версии django-websocket) и, поскольку он представляет собой простой код на python, вы можете импортировать свои модели и все остальное из django.Единственный недостаток - вам нужен второй веб-сервер, работающий только для обработки веб-сокетов.