Подтвердить что ты не робот

Как работает архитектура сервера WebSockets?

Я пытаюсь лучше понять, как серверная архитектура работает для WebSockets с целью ее внедрения во встроенное приложение. Кажется, что здесь есть 3 разных программных компонента на стороне сервера: 1) веб-сервер для обслуживания статических страниц HTTP и обработки запроса на обновление, 2) библиотека WebSockets, такая как libwebsockets для обработки "гаек и болтов" для обмена данными через WebSockets, и 3) мое пользовательское приложение, чтобы на самом деле выяснить, что делать с входящими данными. Как все это сочетается? Общепринято ли иметь отдельный веб-сервер и часть обработки WebSocket, например сервер/демон WebSocket?

Как мое приложение взаимодействует с веб-сервером и/или библиотекой WebSockets для отправки/получения данных? Например, с CGI веб-сервер использует переменные среды для отправки информации в пользовательское приложение и stdout для получения ответов. Что такое эквивалентная система связи здесь? Или вы обычно связываетесь в библиотеке WebSocket с клиентским приложением? Но как будет работать связь с веб-сервером в библиотеке WebSocket + пользовательское приложение? Или все 3 объединены в один компонент?

Вот почему я спрашиваю. Я использую веб-сервер boa на платформе uClinux/no MMU на процессоре Blackfin с ограниченной памятью. В боа нет встроенной поддержки WebSocket, только CGI. Я пытаюсь выяснить, как я могу добавить поддержку WebSockets. Я бы предпочел использовать скомпилированное решение, а не что-то интерпретируемое как JavaScript, Python или PHP. Мое текущее приложение использует длительный опрос по CGI, который не обеспечивает адекватную производительность для запланированных улучшений.

4b9b3361

Ответ 1

Во-первых, важно понять, как устанавливается соединение с WebSocket, поскольку оно играет важную взаимосвязь между соединениями webSocket и вашим веб-сервером.

Каждое соединение с webSocket начинается с запроса HTTP. Браузер отправляет HTTP-запрос хосту/порту, на который запрашивается соединение webSocket. Этот запрос может выглядеть примерно так:

GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Чем отличается этот запрос от любого другого HTTP-запроса на этом сервере, это заголовок Upgrade: websocket в запросе. Это сообщает HTTP-серверу, что этот конкретный запрос на самом деле является запросом инициировать соединение с WebSocket. Этот заголовок также позволяет веб-серверу указывать разницу между обычным HTTP-запросом и запросом на открытие соединения через webSocket. Это позволяет сделать что-то очень важное в архитектуре, и это было сделано целиком. Это позволяет использовать тот же самый сервер и порт для обслуживания ваших веб-запросов и для соединений webSocket. Все, что вам нужно, это компонент на вашем веб-сервере, который ищет этот заголовок Upgrade для всех входящих HTTP-соединений, и, если он найден, он принимает соединение и превращает его в соединение webSocket.

Как только сервер распознает этот заголовок Upgrade, он отвечает юридическим ответом HTTP, но тот, который сигнализирует клиенту о том, что обновление к протоколу webSocket было принято так:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

В этот момент оба клиента и сервер сохраняют этот сокет от исходного HTTP-запроса открытым и оба переключаются на протокол webSocket.


Теперь, к вашим конкретным вопросам:

Как мое приложение взаимодействует с веб-сервером и/или Библиотека WebSockets для отправки/получения данных?

Ваше приложение может использовать встроенную поддержку webSocket в современных браузерах и может инициировать подключение к WebSocket следующим образом:

var socket = new WebSocket("ws://www.example.com");

Это приведет к тому, что браузер запустит соединение webSocket с www.example.com с тем же портом, с которым была связана текущая веб-страница. Из-за встроенной поддержки webSocket в браузере вышеуказанный HTTP-запрос и протокол обновления обрабатываются для вас автоматически с клиента.

На стороне сервера вы должны убедиться, что используете веб-сервер с поддержкой входящей поддержки WebSocket и что поддержка включена и настроена. Поскольку соединение webSocket является непрерывным соединением после его установки, оно действительно не соответствует модели CGI вообще. Должна быть, по крайней мере, одна длительная обработка процессов в режиме реального времени. В моделях серверов (например, CGI) вам понадобится какая-то надстройка веб-сервера, которая поддерживает этот долговременный процесс для ваших соединений в сети. В такой серверной среде, как node.js, который уже является длительным процессом, добавление web-сокетов не изменяется вообще архитектурно, а скорее просто дополнительная библиотека для поддержки протокола webSocket.

Я бы предположил, что вы можете найти эту статью интересной, поскольку она обсуждает этот переход от обработки одного запроса в стиле CGI к непрерывным соединениям сокета webSocket:

Веб-эволюция: от CGI до Websockets (и как это поможет вам лучше контролировать облачную инфраструктуру)

Если вы действительно хотите придерживаться модели stdin/stdout, есть библиотеки, которые моделируют это для ваших веб-узлов. Здесь одна такая библиотека. Их лозунг: "Это похоже на CGI, двадцать лет спустя, для WebSockets".

Я пытаюсь выяснить, как я могу добавить поддержку WebSockets. я предпочла бы использовать скомпилированное решение, а не что-то интерпретируется как JavaScript, Python или PHP.

Извините, но я не знаком с этой конкретной средой сервера. Вероятно, вам потребуется подробный поиск, чтобы узнать, каковы ваши варианты. Поскольку соединение webSocket является непрерывным соединением, вам понадобится процесс, который работает непрерывно, что может быть частью на стороне сервера соединения WebSocket. Это может быть либо встроено в ваш веб-сервер, либо может быть дополнительным процессом, который WebServer запускает и пересылает входящие соединения.

FYI, у меня есть собственное приложение дома, построенное на малине Pi, которое использует webSockets для обмена в реальном времени с веб-страницами браузера, и это работает отлично. Я использую node.js для серверной среды и библиотеки socket.io, которая работает поверх веб-сокетов, чтобы дать мне интерфейс более высокого уровня поверх web-сокетов. Мой серверный код проверяет несколько аппаратных датчиков на регулярном интервале, а затем всякий раз, когда появляются новые/измененные данные для отчета, он отправляет сообщения на любые открытые веб-сокеты, чтобы подключенные браузеры получали обновления в режиме реального времени на показаниях датчиков.

Вероятно, вам понадобится какое-то давно работающее приложение, которое должно было передавать входящие соединения WebSocket с веб-сервера на ваш длительный процесс или вам нужно было бы подключать webSocket к другому порту, чем ваш веб-сервер (чтобы они могли быть, в этом случае у вас будет целый отдельный сервер для обработки запросов и сокетов webSocket (этот сервер также должен будет поддерживать CORS, чтобы браузеры могли подключаться к нему, поскольку это был бы другой порт, чем ваши веб-страницы).