Доброго времени суток читатель!
Я разрабатывал серверную платформу для мобильного приложения. И у меня возникла проблема когда мне нужно было поставить вебсокеты.
Задача была следующей: на определенный url со стороны клиентской части приложения приходит POST запрос, в этот момент в Базу Данных вносятся определенные данные, так же сторона клиента прослушивает другой порт на сервере, по другому протоколу т.е. по протоколу ws. В тот момент когда на сервер приходит запрос по протоколу http необходимо отправить эти данные по протоколу ws.
То что происходит по протоколу http, реализуется с помощью Django rest framework, и запускается на порту 8000(можно поменять). Описывать его работу в статье не буду, у DRF хорошая документация, самый простой код реализации DRF оставлю здесь.
Вся сложность заключается в том что мы должны открыть api по определенному url, и когда на него придет нужный запрос, мы должны сообщить об этом по веб сокетам. Собственно об этом было сказано выше.
На заметку:
Django сам по себе не асинхронный, работает на протоколе http и такая реализация, т.е. протокол ws, на чистой джанге невозможна, для этого джанго-проект нужно с чем то связать.
Теория:
WebSocket - постоянное соединение поверх http(s)
При установлении соединения происходит рукопожатие с помощью специальных http заголовков, после любая сторона в любой момент времени (пока соединение не прервется) может писать в тело запроса сообщения. Каждое такое сообщение представляет из себя передаваемые данные + мета-данные. Более подробно об этом я уже писал в телеграмм канале
Решение:
Для того чтобы реализовать свой коварный план я использовал Tornado версии 3.2.
Мы будем прослушивать порт 5000 локального хоста по протоколу ws.
Запустим следующий код.
Таким образом мы принимаем множество клиентов по протоколу веб сокетов, метод on_message принимает аргумент message, который и отправляется клиентской части приложения.
Теперь создадим такую функцию которая будет вызывать этот самый метод on_message, отдавая туда те данные, которые нам нужно взять из POST запроса, который нам придет. Эту функцию (т.е. метод connect) мы будем вызывать при серилизации, т.е. в файле serializers.py вашего django-проекта.
Функция принимает два аргумента, data это наш словарь с данными, которые мы будем отправлять по сокетам, второй агрумент не нуждается в объяснении.
Для работы веб сокетов мы использовали следующие пакеты:
sockjs==0.9.1
tornado==3.2
websocket-client==0.56.0
Примеры этого кода я оставлю здесь.
Справедливо соглашусь с тем что это не является лучшим решением, и конечно можно сделать красивее, но это все же работает.