Как реализовать работу с WebSocket в старых версиях платформы 1С (8.3.10 и ниже)

Программист 1С v8.3 (Обычные формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

В современной разработке все чаще встречаются задачи интеграции с внешними сервисами, которые работают в режиме реального времени. Если раньше стандартом был обмен файлами или HTTP-запросы, то сейчас многие API (особенно финансовые, биржевые или сервисы общепита) требуют работы по протоколу WebSocket. Это позволяет поддерживать постоянное соединение и мгновенно получать данные.

Однако, мы часто сталкиваемся с ситуацией, когда инфраструктура предприятия построена на старых релизах платформы 1С (например, 8.3.10 или еще старше). Обновление платформы ради одной функции может быть рискованным из-за большого количества "нетипового" кода, накопленного годами. Штатная поддержка WebSocket появилась только в платформе 8.3.25. Давайте разберем подробно, как решить эту задачу на старой платформе, проанализируем доступные архитектурные подходы и выберем оптимальные инструменты.

Проблема: WebSocket и синхронность 1С

Прежде чем переходить к коду, давайте поймем суть проблемы. Протокол HTTP, с которым 1С отлично работает, основан на принципе "запрос-ответ". Мы спросили — нам ответили. WebSocket — это двусторонний канал. Сервер может прислать данные в любой момент, даже если мы его не спрашивали.

1С 8.3.10 (да и более новые версии в синхронном режиме) выполняет код последовательно. Если мы просто попытаемся "слушать" сокет в бесконечном цикле на клиенте, интерфейс пользователя "зависнет" намертво. Поэтому нам нужно искать решения, которые позволят получать данные асинхронно или имитировать это поведение.

Решение 1: Архитектурный подход "Прокси-сервер" (Sidecar)

Один из самых надежных способов, предложенный в обсуждении, — не пытаться заставить старую платформу делать то, для чего она не предназначена, а использовать промежуточное звено.

Суть метода заключается в развертывании микросервиса или использовании COM-подключения рядом с сервером 1С. Рассмотрим схему работы:

  1. Микросервис (написанный на Node.js, Go, Python или даже на современной платформе 1С, опубликованной на другом порту) устанавливает постоянное WebSocket соединение с внешним API.
  2. Этот сервис держит связь, отправляет необходимые заголовки (Headers) и "слушает" эфир.
  3. Как только приходит сообщение от внешнего API, микросервис берет эти данные и отправляет их в нашу базу 1С 8.3.10 обычным HTTP-запросом (POST).

Почему это удобно? Старые версии 1С прекрасно умеют принимать входящие HTTP-запросы через механизм HTTPСервисы. Нам не нужно держать открытое соединение внутри сеанса пользователя.

Преимущества:

Решение 2: Использование .NET Framework (NetObjectToIDispatch)

Если сервер 1С работает под управлением ОС Windows, мы можем воспользоваться мощью платформы .NET, которая уже есть в системе. Для этого часто используют обертку NetObjectToIDispatch или аналогичные разработки, позволяющие создавать классы .NET прямо из кода 1С.

В .NET Framework (начиная с версии 4.5) существует пространство имен System.Net.WebSockets. Давайте посмотрим, как мы можем это использовать. Нам потребуется создать объект ClientWebSocket.

Примерная логика инициализации соединения будет выглядеть так:


// Создаем обертку для работы с .NET
врап = Новый COMОбъект("NetObjectToIDispatch45");
	
// Создаем объект веб-сокета
Сокет = врап.СоздатьОбъект("System.Net.WebSockets.ClientWebSocket");
	
// Добавляем необходимые заголовки (одно из требований задачи)
// Используем CancellationToken (токен отмены) для асинхронных операций
ТокенОтмены = врап.СоздатьОбъект("System.Threading.CancellationToken");

// Устанавливаем заголовки, если API требует авторизации
Сокет.Options.SetRequestHeader("Authorization", "Bearer ВашТокен");
	
// Подключение (Uri - адрес wss://...)
URI = врап.СоздатьОбъект("System.Uri", "wss://api.example.com/stream");
Таск = Сокет.ConnectAsync(URI, ТокенОтмены.None);

// Ожидаем соединения (в реальном коде лучше делать это без Wait, чтобы не блокировать поток надолго)
Таск.Wait();

После установки соединения нам нужно читать данные. Поскольку методы чтения в .NET асинхронные (ReceiveAsync), а 1С — синхронная, нам придется либо использовать методы ожидания .Result или .Wait(), что заблокирует интерфейс, либо выносить этот код в фоновое задание.

Решение 3: Внешние компоненты (Native API и cURL)

Если вариант с .NET кажется сложным или вы работаете на Linux, стоит рассмотреть использование внешних компонент (ВК), написанных по технологии Native API. В частности, существуют ВК-обертки над библиотекой libcurl.

Библиотека cURL (libcurl) является стандартом де-факто для сетевых операций и поддерживает протоколы ws:// и wss://. Использование готовой компоненты снимает головную боль с реализацией протокола рукопожатия (handshake) и шифрования.

При использовании ВК алгоритм действий будет следующим:

  1. Загружаем компоненту: ПодключитьВнешнююКомпоненту(...).
  2. Инициализируем объект компоненты.
  3. Устанавливаем заголовки через методы компоненты, например: Компонента.УстановитьЗаголовок("User-Agent", "1C-Client").
  4. Вызываем метод подключения.

Как избежать блокировки интерфейса?

Самый важный вопрос при работе с WebSocket внутри клиента 1С — как не "заморозить" кассира или менеджера, пока мы ждем сообщение от сервера.

Мы рекомендуем использовать один из двух подходов:

Вариант А: Обработчик Ожидания (для Клиента)

Если мы используем внешнюю компоненту, которая умеет накапливать сообщения во внутреннем буфере, мы можем настроить таймер в 1С.


// В модуле формы
Процедура ПриОткрытии()
    // Подключаем ВК и соединяемся с сокетом
    ПодключитьСокет();
    // Запускаем опрос буфера каждые 0.5 секунды
    ПодключитьОбработчикОжидания("ПроверитьСообщения", 0.5, Ложь);
КонецПроцедуры

Процедура ПроверитьСообщения()
    // Спрашиваем у компоненты, есть ли новые данные
    Данные = ОбъектВК.ПолучитьСледующееСообщение();
    Если Данные <> Неопределено Тогда
        ОбработатьДанные(Данные);
    КонецЕсли;
КонецПроцедуры

Вариант Б: Фоновое задание (для Сервера)

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

В этом задании мы можем запустить "бесконечный" цикл (с разумными прерываниями), который будет висеть на соединении и ждать данные. При получении данных задание записывает их в РегистрСведений. А уже формы пользователей опрашивают этот регистр.

Резюме

Интеграция 1С 8.3.10 с WebSocket — задача решаемая, хоть и требует обходных путей. Давайте подытожим варианты:

  1. Самый безопасный: Поднять рядом маленький сервис-прокси (на Node.js/Go), который перекладывает данные из WebSocket в HTTP-сервис 1С. Это снимает нагрузку с 1С и решает проблему асинхронности.
  2. Для Windows-инфраструктуры: Использовать NetObjectToIDispatch и системные библиотеки .NET. Это позволяет писать код на 1С, но использовать возможности C#.
  3. Кроссплатформенный: Найти внешнюю компоненту (Native API), оборачивающую libcurl.

При реализации обязательно помните про обработку обрывов связи (reconnect) и блокировку интерфейса. В старых релизах платформы пользовательский интерфейс однопоточен, поэтому любые длительные сетевые операции должны быть либо асинхронными, либо вынесенными в отдельные процессы.

← На главную