LINUX.ORG.RU

Push notifications, как?

 , ,


1

2

Как сейчас модно делать push нотификации? (С возможностью по-меньше лишних сущьностей.)

Background:

Пишу маленькую приблуду 4fun&profit, в частности простенький веб-интерфейс на Go к файло-помойке для добавления \ архивирования \ деархивирования проектов.

Веб-итерфейс дёргает shell-скрипт который создаёт и переносит директории. (Хотел сначала сделать всё на самом Go, но оказалось, что там всё совсем не так просто. Поэтому решил вернуться к старым mkdir и mv.) Сам процесс переноса может длиться н-ное время.

Хотелось бы как-то уведомить юзверя, что всё ок или не-ок. Показать статус, мигнуть окошком, когда копирование закончится.

И тут проблема. Как это сделать?

Открыл для себя Server-side events, попробовал сдеть. На макете всё чудесно, но на практике оказалось тоже не тривиально.

По схеме у меня идут GET(view)->POST(command)->REDIRECT->GET(view). И javascript дропает при каждом рефреше коннект к URL уведомлялки. В результате сообщения не доходят. Пробовал вставить задержки, но это мне не нравится.

В общем, просветите пожалуйста, как такое делается?

PS: про JavaScript знаю только, что есть NoScript.

★★★★★

Последнее исправление: beastie (всего исправлений: 1)

я бы сделал на ajax или лучше websockets (про go ничего не знаю)

invokercd ★★★★
()

Хотел сначала сделать всё на самом Go, но оказалось, что там всё совсем не так просто.

а в чем проблема?

anonymous
()
Ответ на: комментарий от anonymous

На что нарвался:

  • в os/user нет GroupLookup: https://code.google.com/p/go/issues/detail?id=2617 А мне они нужны. Но это ещё ерунда. Мне их надо с пол-десятка, можно было бы и захдкодить.
  • Выполнять часть кода мне надо от рута. Разбил на две части (www/root) и объединил через net/rpc. Вроде заработало. (Безопастностью там, правда, и не пахнет.)
  • Но тут всплыла другая поблема: os.Rename не умеет переносить за пределы файловой системы. (Да, rename(2) это тоже не умеет, но это хоть оговорено в мане, в отличаее от godocs). https://code.google.com/p/go/issues/detail?id=6887 А писать свою имплементацию mv с нуля мне как-то разхотелось.

Но к пробемам нотификаций это не относится. ;)

beastie ★★★★★
() автор топика
Последнее исправление: beastie (всего исправлений: 1)

я запилил нечто подобное на SOAP обертке к Ansible. сами сценарии пускаю как celery tasks. на JS нарисован простенький статичный клиент который на стороне клиента периодически дергает SOAP метод мониторинга.

exception13 ★★★★★
()
Ответ на: комментарий от Deleted

Как-то даже не думал в эту сторону...

beastie ★★★★★
() автор топика
Ответ на: комментарий от exception13

У меня там немного больше логики задействованно, чем просто «запустить бекап». Скорее что-то вроде project manager.

Эх, а как хотелось обойтись без JS...

beastie ★★★★★
() автор топика

как предложил первый человек, на вебсокетах сделай.. не сложно. После функции архивирования\еще что-то - делаешь push в канал обратной связи клиенту

Alexoy
()
Ответ на: комментарий от Alexoy

Так тут то мне и не понятно. У меня происходит рефреш страницы. Что происхоит с веб-сокетом? Отваливается?

beastie ★★★★★
() автор топика
Ответ на: комментарий от beastie

«WebSocket connections do not, however, persist across loading of new pages from the same domain, or page reloads. A WebSocket connection only persists as long as the page is still open (not navigated away from)», ага. А очень рефреш нужен? ..может достаточно менять содержание отдельных частей страницы?

Alexoy
()
Ответ на: комментарий от beastie

Websockets этой такой RPC.

Сделал POST, получил ответ, сохранил id ресурсов которые нужно мониторить в localStorage.

Далее, либо сразу же, либо после редиректа (тогда вытягиваешь id-шки которые нужно мониторить из localStorage), открываешь websocket, коннектишься к channel который соответствует твоему ресурсу, там project100500.

С сервера, как кто-то приконнектился отправляешь текущий статус ресурса — инфу которую хотел получить.

Ну и как только ресурс сменил статус, на сервере пишешь в канал project100500 что нужно.

vladimir-vg ★★
()
Последнее исправление: vladimir-vg (всего исправлений: 1)
Ответ на: комментарий от vladimir-vg

Спасибо за разяснение, но это совсем уже выходит за рамки моего Web-Fu. :( Я слабо надеялся, что это будет проще.

Я решил пойти другим путём. Благо есть, где развренутся и я могу разместить current/archive на одном слайсе zfs, а не на двух разных, как было до этого. (На бекапы в удалённое место это никак не сказывается.)

В связи с чем у меня os.Rename снова начинает работать и становится атомарным. Что собственно полностью убирает всю необходимость отложенных нотификаций.

beastie ★★★★★
() автор топика
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

А писать свою имплементацию mv с нуля мне как-то разхотелось.

А многие сказали бы спасибо.

anonymous
()
Ответ на: комментарий от anonymous

К сожалению там даже uid/gid файлу толком не поставишь. (Мне нужен preserve mv.)

Узнать uid/gid старого файла из os.Fileinfo можно только вот таким, непортабельным, костыльным способом:

fi.Sys().(*syscall.Stat_t).Uid

В общем, там куча подводных камней и нет никаких гарантий, что не забудешь какой-нибудь corner-case.

ref: https://groups.google.com/forum/#!topic/golang-nuts/ywS7xQYJkHY

beastie ★★★★★
() автор топика
Последнее исправление: beastie (всего исправлений: 1)

В сервере делаешь внутреннюю структуру. taskId -> task. taskId это число.

При запуске задачи ей присваивается taskId и пользователю возвращается редирект на адрес /tasks/{taskId}.

При запросе этой страницы сервер проверяет статус задачи {taskId} и возвращает текст мол работаем или всё готово.

На страницу добавить простой Javascript:

setTimeout(function () { window.location.reload(); }, 10000);

он будет через 10 секунд перезагружать страницу. В принципе всё.

Legioner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.