Осуществляется через HTTP/1.1 (постоянное HTTP-соединение), работает под традиционным TCP Port 80 (TCP портом 80). HTTPS не используется, вместо этого используется упомянутый выше метод шифрования.
Соединение HTTP прикреплено к сессии (или скорее к идентификатору сессии+ключа), указанной в последнем полученном запросе юзера; обычно сессия одна и та же во всех запросах, но коварные HTTP прокси могут исказить это. Сервер может не вернуть сообщение в HTTP соединение, если оно не принадлежит к одной и той же сессии, и если не наступила очередь сервера (когда от клиента был получен HTTP запрос, на который ещё не был отправлен ответ).
Общий механизм следующий: клиент открывает одно или более постоянных HTTP-соединений с сервером; если должны быть отправлены одно или более сообщений, они объединяются под одним payload'ом, после которого следует POST запрос к URL/api к которому payload передаётся в виде данных. Кроме того, Content-Length, Keepalive, and Host являются действующими HTTP заголовками.
Получая запрос, сервер может или подождать некоторое время (если запрос требует ответа после короткого тайм-аута) или немедленно вернуть макет ответа (dummy response) (лишь подтверждая получение контейнера). В любом случае, ответ может содержать любое количество сообщений. Сервер может одновременно отправлять любые другие сообщения, которые содержит сессия.
|
|
Дополнительно, существует специальная очередь ожидающих RPC запросов (действующая только для HTTP соединений), которая передаёт/справляется с максимальной задержкой Т. Если у сервера есть сообщения для сессии, они возвращаются немедленно, в противном случае, включается режим ожидания до того времени, пока у сервера есть сообщение для клиента, или пока не пройдёт Т секунд. Если ничего не происходит за Т секунд, возвращается макет ответа.
Если серверу нужно послать сообщение клиенту, он проверяет HTTP соединение, которое принадлежит к нужной сессии и находится в состоянии "ответ на HTTP запрос" (включая очередь запросов), после чего сообщение добавляется к контейнеру ответа и отправляется юзеру. В типичном случае, есть некое дополнительное время ожидания (50 миллисекунд) на случай, что у сервера скоро будет больше сообщений для сессии.
Если нет подходящего доступного HTTP соединения, сообщения помещаются в очередь отправки текущей сессии. Однако они найдут свой путь до того как получение будет прямо или косвенно подтверждено сервером. Для HTTP протокола, отправка следующей очереди в том же HTTP соединении считается подтверждением (с этого момента HTTP протокол больше не требует, чтобы подтверждение было отправлено); в других случаях, клиент должен отправить точное подтверждение в течение допустимого времени (оно может быть добавлено к контейнеру для следующего запроса).
|
|
ВАЖНО. Если подтверждение не пришло вовремя, сообщение может быть отправлено заново (возможно, в другом контейнере). Объекты должны быть автономно подготовлены к этому и должны сохранить (записать) идентификаторы самых последних принятых сообщений (и игнорировать дубликаты, а не повторять действия). Чтобы не хранить идентификаторы вечно, существуют специальные сообщения-"сборщики мусора", которые пользуются однообразием идентификаторов сообещний.
Если отправленная очередь переполняется или если сообщения остаются в очереди дольше 10 минут, сервер забывает их (или отправляет в своп (swap), ничего особенного сдесь делать не требуется). Это может произойти даже быстрее, если у сервера закончилось буферное пространство (например, потому что серьёзные проблемы с сетью привели к большому количеству разорванных соединений).