- Общие принципы работы с локальными проектами
- План проекта веб-сервиса копирования сделок и сигналов
- Веб-сервер на основе nodejs
- Теоретические основы протокола WebSockets
- Серверная часть веб-сервисов на базе WebSocket-протокола
- Протокол WebSocket-ов на MQL5
- Клиентские программы эхо и чат-сервисов на MQL5
- Сервис торговых сигналов и тестовая веб-страница
- Клиентская программа сигнального сервиса на MQL5
Теоретические основы протокола WebSockets
Протокол WebSocket-ов строится поверх сетевых соединений TCP/IP, которые характеризуются IP-адресом (или заменяющим его доменным именем), а также номером порта. По такому же принципу работает и протокол HTTP/HTTPS, с которым мы уже практиковались в главе про сетевые функции. Там стандартными номерами портов были 80 (для незащищенных соединений) и 443 (для защищенных). Для WebSocket не существует выделенного номера порта, поэтому поставщики веб-сервиса могут выбрать любой свободный номер. Во всех наших примерах будет использоваться порт 9000.
При задании URL в качестве префиксов протокола WebSocket-ов применяются ws (для незащищенных соединений) и wss (для защищенных).
Формат WebSocket-ов более эффективен в плане передачи данных, чем HTTP, так как использует гораздо меньший объем управляющих данных.
Начальное установление соединение для WebSocket-сервиса полностью повторяет запрос веб-страницы HTTP/HTTPS: нужно отправить GET-запрос со специально подготовленными заголовками. Особенностью этих заголовков является наличие строк:
Connection: Upgrade
|
а также некоторых дополнительных, сообщающих версию протокола WebSocket-ов и специальные случайно сгенерированные строки — ключи, участвующие в процедуре "рукопожатия" (handshaking) клиента и сервера.
Sec-WebSocket-Key: ...
|
На практике "рукопожатие" заключается в проверке сервером доступности тех опций, которые запросил клиент, и в ответе со стандартными HTTP-заголовками, подтверждающими переключение в режим WebSocket-ов или отклоняющими его. Самой простой причиной отклонения может быть, если вы пытаетесь подключиться по протоколу WebSocket-ов к простому веб-серверу, где WebSocket-сервер не предусмотрен или не поддерживается нужная версия.
Актуальная версия протокола WebSockets известна под символическим именем Hybi и номером 13. Существующая более ранняя и простая версия Hixie может быть полезна для обеспечения обратной совместимости. Далее мы будем использовать только Hybi, хотя реализация Hixie также прилагается.
Успешное подключение обозначается такими HTTP-заголовками в ответе сервера:
HTTP/1.1 101 Switching Protocols
|
Поле Sec-WebSocket-Accept здесь рассчитывается и заполняется сервером на основе ключа Sec-WebSocket-Key, чтобы подтвердить соответствие протоколу. Все это регламентировано спецификацией RFC6455 и будет поддержано также и в наших MQL-программах.
Для наглядности процедура показана на следующем изображении:
Взаимодействие клиента и сервера по протоколу WebSocket-ов
После установления WebSocket-соединения клиент и сервер могут обмениваться информацией, упакованной в специальные блоки: фреймы и сообщения. Сообщение может состоять из одного или нескольких фреймов. В принципе, размер фрейма, согласно спецификации, ограничен астрономическим числом 263 байтов (9223372036854775807 ~ 9.22 эксабайт!), но конкретные реализации, разумеется, могут иметь более приземленные ограничения, поскольку данный теоретический лимит не кажется практичным для пересылки одним пакетом.
В любой момент клиент или сервер могут разорвать соединение, предварительно "вежливо попрощавшись" (см. ниже) или просто закрыв сетевой сокет.
Фреймы бывают разных типов, что задается в их заголовке (длиной от 4 до 16 байтов), который идет в начале каждого фрейма. Перечислим для справки операционные коды (они присутствуют в первом байте заголовка) и назначение фреймов разных типов.
- 0 — фрейм продолжения (наследует свойства предыдущего фрейма);
- 1 — фрейм с текстовой информацией;
- 2 — фрейм с двоичной информацией;
- 8 — фрейм запроса закрытия и подтверждения закрытия соединения (посылаются для "вежливого прощания");
- 9 — пинг-фрейм, может периодически посылаться любой из сторон, чтобы убедиться в физическом сохранении соединения;
- 10 — понг-фрейм, отправляется в ответ на пинг-фрейм.
Последний фрейм в сообщении помечается особым битом в заголовке. Разумеется, когда сообщение состоит из одного фрейма, он же является и последним. Также в заголовке передается длина полезных данных.