Пару месяцев назад устроился на обычную работу. Больше для дисциплины, но и деньги кончились от двухмесячного валяния дурака. Делаем там внутреннюю систему продвижения собственных сайтов. Довольно много процедур длительных и вынесены в фон. Но красиво же, когда состояние задач обновляется автоматически. Погуглил Websocket comet-серверы. Ничего интересного не нашел. Все какое-то навороченное: с базами данных, кучей зависимостей. Решил написать свой простенький. Можно было писать на питоне и asyncio, но мне показалось, что такую задачу лучше решить микросервисом на Go. Получилось вроде неплохо. Нужные задачи выполняет хорошо. Хотя есть куда развивать. Итак, собственно сам Golang Push-server.
А теперь, как им пользоваться:
На странице нужно подключить скрипт pusher.js.
А затем подписаться на любое событие:
pushSub(«событие»,function(obj) {});
В коллбэк передается объект от сервера. Я использую такую маркировку: событие: «канал.приложение.объект[.ид_объекта, если нужен]». Сервер передает {«id»:123, «status»: «completed»}
Отписаться от события можно с помощью
pushUnsub(«событие»);
В python/django можно приложениях можно воспользоваться готовым модулем pusher.py:
from pusher import push_intent
push_intent(intent, obj)
В качестве объекта можно передать строку, словарь, список или ничего. Событие всегда строковое. Сервер находит подписчика на именно это событие и отправляет ему оповещение. В будущем можно будет реализовать маску типа «channel.app.*».
Теперь, как это работает на более низком уровне:
При загрузке страницы клиент подключается к ws://сервер:8095/sub (порт пока фиксированный) и отправляет:
{«op»: «sub», «intent»: «channelname.taskname.12345»}
Сервер пока ничего не возвращает. Если сообщение отправилось, значит подписка активна.
Приложение на сервере просто отправляет post/get запрос:
http://сервер:8095/pub?intent=channelname.taskname.12345?obj={«id»:123}
И если push-сервер находит подключенного подписанного клиента, отправляет ему сообщение вида:
{«op»: «intent», «intent»: «channelname.taskname.12345», «obj»: {\»id\»:123}»}
При отключении клиента, все его подписки удаляются. Поэтому нужно будет предусмотреть переподключение и переподписывание в JS-библиотеке.