Как реализовать REST API сервер в 1С 7.7 для мобильных сканеров с использованием NetObjectToIDispatch45

Программист 1С v7.7 Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

Разработка современных решений на базе 1С:Предприятие 7.7 часто упирается в отсутствие встроенных механизмов для работы с веб-протоколами. Одной из наиболее востребованных задач является создание HTTP-сервиса внутри «семерки», который мог бы принимать данные от мобильных Android-приложений (например, при сканировании штрихкодов на входе на мероприятие) и мгновенно возвращать ответ. Рассмотрим, как реализовать полноценный REST-сервер, используя возможности библиотеки NetObjectToIDispatch45, и разберем типичные ошибки реализации.

Архитектура решения: HttpListener внутри 1С

Для того чтобы 1С 7.7 начала «слушать» входящие GET-запросы, мы воспользуемся стандартным классом .NET Framework — System.Net.HttpListener. Этот класс позволяет создать легковесный HTTP-сервер без установки громоздких систем вроде IIS. Проанализируем общую схему: мобильное устройство отправляет запрос на IP-адрес ноутбука, где запущена 1С, компонента перехватывает этот запрос, передает его в код 1С для обработки, после чего мы формируем ответ и отправляем его обратно устройству.

Реализация сервера и исправление ошибки GetBytes

Одной из главных проблем, с которой сталкиваются разработчики при переносе кода с C# в 1С 7.7, является работа с абстрактными классами и типами данных. В частности, попытка вызвать метод GetBytes напрямую у типа Encoding приводит к ошибке «Поле агрегатного объекта не обнаружено». Это происходит потому, что в .NET Encoding — это базовый класс, и нам нужно получить доступ к конкретному экземпляру (например, UTF8).

Разберем исправленный и дополненный код для запуска прослушивания порта:


Процедура ЗапуститьСервер()
    Попытка
        // Инициализируем компоненту для работы с .NET
        net = СоздатьОбъект("NetObjectToIDispatch45");
        net.УстЭтоСемерка();
        
        // Создаем объект прослушивания
        listener = net.СоздатьОбъект("System.Net.HttpListener");
        // Указываем префикс. Символ * означает прослушивание всех входящих IP
        listener.Prefixes.Add("http://*:8080/");
        listener.Start();
        
        Сообщить("Сервер запущен на порту 8080. Ожидание запроса...");
        
        // ВНИМАНИЕ: GetContext() блокирует выполнение 1С до получения запроса
        context = listener.GetContext();
        request = context.Request;
        
        // Извлекаем URL запроса, например: /ScanTicket.aspx?barcode=12345
        RawUrl = request.RawUrl;
        Сообщить("Получен запрос: " + RawUrl);
        
        // Здесь должна быть логика поиска билета в базе 1С
        РезультатОбработки = "Билет действителен. Проходите.";
        
        // Формируем ответ
        response = context.Response;
        
        // РЕШЕНИЕ ПРОБЛЕМЫ С GetBytes:
        // Сначала получаем тип кодировки, затем ее статический экземпляр UTF8
        ТипКодировки = net.ПолучитьТип("System.Text.Encoding");
        КодировкаUTF8 = ТипКодировки.UTF8;
        
        // Преобразуем строку ответа в массив байтов
        buffer = КодировкаUTF8.GetBytes(РезультатОбработки);
        
        // Записываем данные в поток ответа
        response.ContentLength64 = buffer.Length;
        output = response.OutputStream;
        output.Write(buffer, 0, buffer.Length);
        
        // Закрываем потоки
        output.Close();
        listener.Stop();
        
        Сообщить("Ответ отправлен успешно.");
        
    Исключение
        Сообщить("Ошибка сервера: " + ОписаниеОшибки());
        Если ПустоеЗначение(listener) = 0 Тогда
            listener.Stop();
        КонецЕсли;
    КонецПопытки;
КонецПроцедуры

Настройка прав доступа в операционной системе

Проанализируем важный нюанс: даже если код написан верно, операционная система Windows (начиная с Vista и выше) блокирует попытки приложений занять порт для прослушивания без явного разрешения. Это вызывает ошибку Access Denied. Чтобы Android-приложения могли достучаться до 1С, необходимо выполнить регистрацию URL-адреса в системе.

Запустите командную строку (cmd) от имени администратора и выполните следующую команду:

netsh http add urlacl url=http://*:8080/ user=Все

Важно: Если у вас английская версия Windows, вместо Все используйте Everyone. Также не забудьте открыть порт 8080 во встроенном брандмауэре Windows или временно отключить его для тестирования в локальной сети.

Проблема блокировки интерфейса и пути её решения

Выясним причину, по которой прямое использование GetContext может быть неудобным. Этот метод является синхронным. Это означает, что пока 1С ждет сканирования билета, программа будет выглядеть «зависшей»: оператор не сможет нажать кнопки, сформировать отчет или свернуть окно. Для систем контроля доступа с высокой нагрузкой это недопустимо.

Рассмотрим два способа обхода этой ситуации:

  1. Использование внешнего события: Вместо написания сервера внутри 1С, можно использовать небольшую внешнюю программу (написанную на Go, Python или C#), которая будет принимать HTTP-запросы и передавать их в 1С через механизм ВнешнееСобытие. В этом случае 1С всегда будет отзывчивой.
  2. Циклический опрос с прерыванием: Можно реализовать цикл, который проверяет наличие запроса короткое время, а затем отдает управление системе через ВвестиСтроку с таймаутом или использование компоненты FormEx для обработки ожидания.

Обработка нескольких запросов одновременно

Если на мероприятии работает 10 контролеров, запросы могут приходить практически одновременно. 1С 7.7 — это однопоточное приложение. Чтобы избежать очередей и таймаутов на мобильных устройствах, рекомендуется минимизировать время обработки запроса. Посмотрим на алгоритм оптимизации: - Получение штрихкода. - Быстрый поиск по индексированной таблице (используйте НайтиЗначение или прямые запросы через 1С++). - Мгновенная запись факта прохода. - Закрытие соединения.

Если требуется хранить сложную историю или выводить звук на телефоне («Гражданство отозвано»), лучше формировать ответ в формате JSON. Хотя в 7.7 нет встроенного парсера JSON, для формирования ответа достаточно простой склейки строк:


ТекстОтвета = "{""status"":""ok"", ""message"":""Билет найден"", ""audio"":""welcome.mp3""}";
buffer = КодировкаUTF8.GetBytes(ТекстОтвета);

Альтернатива: Использование промежуточной базы

Если стабильность работы 1С 7.7 вызывает опасения при большом потоке людей, разберем архитектуру с «прокладкой». В качестве сервера выступает скрипт, который записывает все пришедшие штрихкоды в простую базу данных (например, SQLite или даже текстовый файл), а 1С 7.7 в реальном времени считывает эту таблицу. Это разделяет транспортный уровень (прием HTTP) и бизнес-логику (проверка билета в 1С), что делает систему значительно более отказоустойчивой в условиях плохого Wi-Fi или высокой нагрузки.

Использование NetObjectToIDispatch45 открывает для «старой доброй семерки» двери в мир современных интеграций, позволяя не отказываться от отлаженных годами систем учета в пользу громоздких новых конфигураций там, где важна скорость и автономность.

← На главную