Передача данных с сервера на клиент через WebSocket NativeAPI и Centrifugo


В статье описываю реализацию обмена для замены передачи сообщений через 1С Сервер взаимодействия.

Вводные:

1. Используем уведомления пользователей о входящих звонках.
2. Транспортом сообщений является "1С Сервер взаимодействия". В связи с лицензионной политикой дальнейшее использование невозможно.
 

Вариант решения:

1. Использование WebSocket соединений на клиентской части.
2. Использование HTTP API интерфейса на серверной. Поднимать WebSocket соединение на сервере неудобно.
 

Организация WebSocket сервера:

Первое что попалось при "гуглении" https://github.com/centrifugal/centrifugo. Прост в настройке и использовании.
Для тестирования скачал дистрибутив для windows c https://github.com/centrifugal/centrifugo/releases.
Запустить как сервис для windows не получилось, не передает код ответа и сервис не стартует.
Планирую запускать на виртуальной nix, дополнительно можно настроить безопасность с помощью NGINX.
 
Для запуска нужно
1. Распаковать zip архив
2. Запустить генерацию типового конфигурационного файла
centrifugo genconfig

3. Запустить сервис

centrifugo --config=config.json

Сервис запустится на localhost:8000

Реализация подключения клиента

Использую NatieAPI компоненту.

Компоненту приобрел у //infostart.ru/public/1112969/, умеет генерировать внешнее событие.

Подключение компоненты реализовал в общем модуле, сделал обращения к нему из МодуляПриложения
 

 Подключение компоненты

 

Далее анализирую сообщения от внешней компоненты

 

 Анализ сообщений от компоненты

 

И создаю подключение

 

 Создание подключения и подписка на канал

 

Для Аутентификации используется JWT, реализацию брал из //infostart.ru/public/611505/, исходный код https://github.com/pintov/1c-jwt

В качестве имени канала использую GUID текущего пользователя, смысла слать broadcast запросы в моей задаче нет. Канал создается при подписке на него хотя бы одного клиента. То что сообщения не будут доставлены до клиента при отключении в данный не критично, доставляю оперативные уведомления.

Обрабатываю сообщения от компоненты на клиенте

 

 Вариант обработки сообщений

 

Реализация отправки сообщений с сервера

Для отправки использую HTTP протокол

 

 Пример реализации отправки

 

При отправке используется Аутентификация по токену

 

 Пример настройки HTTP запроса

 

В результате получаем:

Реализовывал в виде расширения в которое включена компонента, поэтому все расширение не публикую.

Проверка подключений и восстановление:

Реализовано через ОбработчикОжидания, он обращается к глобальному клиентскому модулю который не видит переменную объявленную в модуле приложения, поэтому вызов передается в не глобальный клиентский общий модуль.

 

 Подключение

 

 Реализация проверки на клиенте

 

Состояния подключений фиксирую в РС "ph_srv_Centrifugo_СостоянияПодключений"

 

 Запись и запрос данных из РС

Установка и запуск как служба:

Windows: успешно создал службу из exe с помощью https://nssm.cc/, при использовании sc служба не запускалась.

Ubuntu 18.04:

1. Запускаем строку

curl -s https://packagecloud.io/install/repositories/FZambia/centrifugo/script.deb.sh | sudo bash

из https://packagecloud.io/FZambia/centrifugo/install, раздел Installation, это настроит подключение к репозиторию, далее запускаем

sudo apt install centrifugo

Проверяем что запустился сервис (конфиг генерируется при установке)

sudo service centrifugo status

 

8 Comments

  1. Steelvan

    *) Для обертки приложения в службу можно использовать nssm https://www.nssm.cc/

    *) Условно-бесплатная компонента для веб-гнезд с поддержкой «Внешнее Событие» https://infostart.ru/public/808432/

    Reply
  2. Steelvan

    Про «поднимать веб-гнезда на сервере сложно» согласен. Через костыли.

    Что бы экземпляр компоненты жил в потоке на сервере этот самый поток надо создать.

    Как вариант, написать фоновое задание, которое будет создавать поток.

    Этот поток передать во внешнюю компоненту вызовом метода и удерживать его там, передавая управление 1С только при получении сообщения.

    Пока Истина Цикл

    Сообщение = ВнешняяКомпонента.ПолучитьСообщение() // Здесь поток замирает до получения сообщения

    ОбработкаСообщения(Сообщение);

    КонецЦикла

    Для этого можно использовать https://infostart.ru/public/937068/

    Reply
  3. malikov_pro

    (2) В моем случае нет смысла,

    1. если что-то нужно передать на сервер, то вызов серверного метода,

    2. если нужно отправить сообщение другому пользователю то организовать канал public и в него писать.

    В Публикации 937068 нет описания функций. Загонять в бесконечный цикл с ПолучитьСообщение() не самое лучшее решение. В той что использую используется нормальный механизм.

    Reply
  4. sivin-alexey

    У нас есть компонента CentrifugoClient (основана на WebSocketClient), которая уже заточена под Centrifugo. Используем её на предприятии уже больше года. Скоро опубликую.

    В CentrifugoClient реализованы методы: ‘Connect’, ‘Refresh’, ‘Disconnect’, ‘Subscribe’, ‘Unsubscribe’, ‘Publish’, ‘Presence’, ‘History’, ‘Ping’, ‘CreateToken’

    Reply
  5. sivin-alexey

    Пример обмена CentrifugoClient и Android будет рассмотрен в публикации.

    Reply
  6. user1286781
    Запустить как сервис для windows не получилось, не передает код ответа и сервис не стартует.

    Вообще Centrifugo работает под Windows, по крайней мере запускается и пускает в административный веб-интерфейс:

    C:Usersadmin>centrifugo.exe —admin
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»starting Centrifugo 2.2.2 (go1.12.6)»}
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»config path: C:\Users\admin\config.json»}
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»pid: 12684″}
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»engine: Memory»}
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»gomaxprocs: 4″}
    {«level»:»info»,»time»:»2019-09-27T11:50:44+03:00″,»message»:»serving websocket, SockJS, API, admin endpoints on :8000″}
    {«level»:»info»,»time»:»2019-09-27T11:53:11+03:00″,»message»:»signal received: interrupt»}
    {«level»:»info»,»time»:»2019-09-27T11:53:11+03:00″,»message»:»shutting down, wait…»}
    

    Показать

    Reply
  7. malikov_pro

    (6) В ручную запустить возможно, но настроить запуск как «Службу» (чтобы запускалась при запуске windows без необходимости запускать сеанс пользователя) у меня не получилось. Пробовал https://support.microsoft.com/ru-ru/help/251192/how-to-create-a-windows-service-by-using-sc-exe. Для меня не критично, потому что планирую развернуть на отдельной виртуальной машине с ubuntu.

    Reply
  8. malikov_pro

    (6) Описание запуска в качестве сервиса windows добавил в статью.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *