Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Примитивный метод добавить WebSocket в Django

Anna | 15.06.2014 | нет комментариев

Примечение переводчика: вебсокеты и Django — это достаточно трудная тема, которая теснее не раз подымалась на програпрогре и стержневой идеей является написание параллельного бэкенда для вебсокетов. Автор же предлагает достаточно лаконичное решение этой задачи, которому правда еще предстоит проверка временем.

TL;DR — Я пришел к дюже простому решению для работы с вебсокетами в Django. Все что вам необходимо — это установить django-websocket-request, запустить скрипт, и сейчас ваше приложение поддерживает вебсокеты! Это решение принуждает Django думать, словно он получает типичный (в какой-то мере) HTTP-запрос, следственно оно будет совместимо примерно со каждому вашим присутствующим кодом. Решение работает типично как с Django Rest Framework, так и с обыкновенными функциями-представлениями и представлениями, основанными на классах (Class Based Views).

Подробнее

Мы разрабатываем Blimp 2 — это говорит о том, что у нас непрерывно уйма изменений в коде и инфраструктуре, и о том, как мы решаем ветхие и новые задачи. Одно из решений, которое мы сделали в отношении нашего приложения, значительно изменило взаимодействие фронтенда и бэкенда.

В данный момент Blimp работает на Django. Он обслуживает наш HTML-код, обрабатывает наше публичное и приватное API, всю бизнес-логику. До последнего времени множество веб-приложений приблизительно так и строились, впрочем Blimp имеет толстый JavaScript-заказчик. С обыкновенными запросами все происходит приблизительно дальнейшим образом: вы запрашиваете URL, происходит какая-то работа со стороны бэкенда — запросы к базе данных, кеширование, обработка данных, отрисовка HTML-страниц, подгрузка сторонних CSS и JavaScript-библиотек, загрузка нашего собственного JavaScript-приложения, еще немножко обработки данных, и наконец отрисовка итога.

Через несколько месяцев практики и роста нашего плана, мы нашли несколько ключевых совершенствований, которые мы можем внедрить — новая версия бэкенда должна будет заниматься образованием JSON, но не отрисовкой HTML, а наше фронтенд-приложение, которое выполняется со стороны заказчика, будет легко потреблять данные через API. Мы решили, что оно будет применять вебсокеты там, где это допустимо, и обыкновенный XHR во всех остальных случаях.

Веб-фреймворк Django и ему сходственные возведены для работы с циклом HTTP-запрос/ответ, следственно всё в них, и представления, и механизмы аутентификации принимают HTTP-запрос на входе и отдают HTTP-результат на выходе. С иной стороны, сервер вебсокетов не знает ничего о таком цикле.

Нашими основными целями были:
1. Одни и те же механизмы сериализации и десериализации данных, как со стороны HTTP-бэкенда, так и со стороны API вебсокетов.
2. Одна и та же бизнес-логика для всех.

Первой мыслью, которая пришла в голову, было перевоплощение каждой бизнес логики в способы наших моделей. Таким образом мы могли бы написать код однажды и поделить его между двумя бэкендами. В тот момент это казалось верным решением, но через несколько часов было подтверждено, что нет. Так как мы трудимся поверх Django REST framework, мы были бы обязаны унаследовать и доработать десятки его классов и примесей, что на самом деле звучало не так уж нехорошо, но мы были настроены довольно скептически и решили поискать другие идеи.

Мы знали, что хотим цельное REST API, которое бы работало по двум каналам: HTTP и вебсокеты. Самым лучшим вариантом стало бы избежание переписывания чего бы то ни было только для работы его с вебсокетами. В какой-то момент меня озарило. Я припомнил о Sails.js, тот, что делает кое-что сходственное с тем, чего мы хотим достичь.

Sails поддерживает непривязанный к определенному механизму обмен данными, что дозволит вашим обработчикам механически трудиться и с Socket.io, и с вебсокетами. В прошлом вам пришлось бы писать обособленный код, Дабы получить такой итог.

Говоря больше простым языком, мы хотели внедрить непривязанный ни к чему определенному механизм обмена данными, тот, что бы дозволил нам применять все что есть из Django-цикла запрос/ответ, Дабы механически формировать вебсокет-сообщения.

Решение

WebSocketRequest оказался невзначай простым решением. Это примитивный класс, тот, что принимает JSON-строку, содержащую следующие ключи: method, url, data, и token. Ключ method может быть любым HTTP-способом: GET, POST, PUT, DELETE, PATCH, HEAD либо OPTIONS. Ключ url является безусловным URL без доменного имени. Ключ data — это добровольный параметр — словарь, содержащий данные. Ключ token также является необязательным — применяется для воссоздания заголовка HTTP-авторизации, авторизации через JSON Web Token либо для ваших собственных ключей. Вы можете посмотреть мою статью , Дабы узнать огромнее о JSON Web Token, а если вы пользуетесь Django REST framework, то вам вероятно понравитсяdjango-rest-framework-jwt.

WebSocketRequest работает дальнейшим образом:

  1. Проверяет пришедшую JSON-строку
  2. Создает экземпляр фабрики запросов (RequestFactory)
  3. Динамически вызывает один из способов фабрики запросов, тот, что возвращает экземпляр WSGIRequest
  4. Находит соответствующее URL представление
  5. Запускает обнаруженное представление совместно со всеми данными, которые пришли из URL.

Да-да, фабрика запросов, вы прочитали правильно. Вы можете быть знакомы с ней, если когда-нибудь писали тесты для Django-приложений, но если нет, фабрика запросов занимается тем, что генерирует объект запроса, тот, что может быть использован как довод для всякого представления. Исключительным минусом является то, что такой запрос не поддерживает механизм middleware, что для некоторых может стать задачей.

Мне определенно хотелось бы услышать о допустимых загвоздках данного подхода. В чем он может быть усовершенствован? Что может сломаться? Что насчет индустриального применения?

Демо

Обратите внимание, что Django в этом примере не применяется вообще. Tornado выдает статический HTML-файл и передает все вебсокет-запросы django-websocket-request, в котором теснее и происходит каждая магия.

Я установил демо-приложение на Heroku: http://dwr-example.herokuapp.com/. Будьте внимательны, данные периодично стираются. Если вы найдете какую-то ошибку, напишите мне в твиттере о ней.

Вы можете установить WebSocketRequest при помощи pip:

pip install django-websocket-request

Начальный код:
https://github.com/GetBlimp/django-websocket-request

Демо-приложение:
https://github.com/GetBlimp/django-websocket-request-example

 

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB