Как HTTP-инстанс знает, что делать с WebSocket Instance? - PullRequest
0 голосов
/ 28 октября 2018

В Cloud Foundry возникла проблема с этим сценарием:

  • Устройство подключается к экземпляру WebSocket в облачной среде
  • Тогда только один экземпляр в CF содержит сокетное соединение
  • Angular UI отправляет запрос в экземпляр REST
  • Экземпляр REST должен выполнить действие на устройстве

Вопрос:

Как мне вызвать нужный экземпляр WebSocket для доступа к устройству?

Cloud Foundry with Web Sockets

Спасибо!

Serge.

Ответы [ 3 ]

0 голосов
/ 29 октября 2018

Как HTTP-инстанс знает, что делать с WebSocket Instance для вызова?

Мой ответ таков: они не должны.

Управление внутренним пулом информации об экземпляре и пользователеданные о подключении могут усложнить ситуацию и привести к разочарованию в масштабируемости (и удобстве обслуживания).

Как вызвать правильный экземпляр WebSocket для доступа к устройству?

Лучший подходIMHO, это использовать базу данных pub / sub, такую ​​как Redis (или услугу pub / sub, которая является более дорогим решением).

Экземпляр соединения WebSocket «подписывается» (слушает) на уникальноечастный "канал" (поток сообщений pub / sub).

Соединение REST "публикует" (отправляет данные) на канал.

Если пользователь подключен к сети, он будетпрослушивание (подписка), и они получат данные, используя подход «push» (опрос не требуется).Если никто не слушает, сообщение просто исчезнет в пустоте.

Соединение WebSocket может также подписаться на публичный / глобальный канал для глобальных уведомлений.

Этот подход создает разделение междуотправитель / издатель (вызов REST) ​​и получатель (подписанный WebSocket).

Это очень упрощает масштабирование, поскольку база данных pub / sub (в данном примере Redis) будет обрабатывать любую переадресацию сообщений.

Это также позволит одному пользователю подключаться с разных компьютеров (например, ноутбуков и телефонов) и получать уведомления на обеих машинах без необходимости обрабатывать IP-адреса и без маршрутизации пользователя на конкретный сервер..

0 голосов
/ 31 октября 2018

Как я уже писал, я не хотел настраивать систему обмена сообщениями, такую ​​как RabbitMQ, просто для отправки простой команды на устройство через веб-сокет.Избыточное убийство!

После поиска я наконец-то нашел решение для нацеливания на правильный экземпляр.

1 \ Когда устройство открывает веб-сокет для сервера WebSocket, я сохраняю идентификатор приложения CF + идентификаторИндекс экземпляра CF в базе данных в виде «APP_ID: INSTANCE_INDEX».

Вы можете получить эту информацию с помощью этого кода в nodejs в CF env.vars:

const cfenv = require('cfenv');

let appID = cfenv.getAppEnv().app.application_id;
let instanceIndex = cfenv.getAppEnv().app.instance_index;

2 \ Когда пользователь запускает действие в Angular UI, которое будет вызывать REST-сервер, этот получает команду и получает «APP_ID: INSTANCE_INDEX» из БД для данного устройства.

3 \ Далее я открываю WebSocket с сервера REST по направлению к серверу WebSocket, ориентируясь именно на экземпляр, который содержит сокет, к которому подключено целевое устройство, добавляя этот заголовок HTTP: «X-CF-APP-INSTANCE ":" APP_ID: INSTANCE_INDEX ".

  // Create WS
  this._wsConnection = new WebSocket(this._serverURL, {
    protocol: 'rest',
    headers: { 'X-CF-APP-INSTANCE': 'APP_ID:INSTANCE_INDEX' }
  });

4 \ Сервер WebSocket получает запрос от сервера REST и обрабатывает его с нужным устройством и возвращает результат на сервер REST, который вернет его.в угловой интерфейс.

Et вуаля!Проблема в разрешении!

0 голосов
/ 29 октября 2018

Это немного сложно, но возможно.Сначала взгляните на получение статистики для процесса .Вы можете использовать это с заголовком X-CF-APP-INSTANCE, чтобы обратиться к каждому экземпляру и увидеть, какой из них имеет соединение с websocket, которое вы ищете.

...