Разработка современных решений на базе 1С:Предприятие 7.7 часто упирается в отсутствие встроенных механизмов для работы с веб-протоколами. Одной из наиболее востребованных задач является создание HTTP-сервиса внутри «семерки», который мог бы принимать данные от мобильных Android-приложений (например, при сканировании штрихкодов на входе на мероприятие) и мгновенно возвращать ответ. Рассмотрим, как реализовать полноценный REST-сервер, используя возможности библиотеки NetObjectToIDispatch45, и разберем типичные ошибки реализации.
Для того чтобы 1С 7.7 начала «слушать» входящие GET-запросы, мы воспользуемся стандартным классом .NET Framework — System.Net.HttpListener. Этот класс позволяет создать легковесный HTTP-сервер без установки громоздких систем вроде IIS. Проанализируем общую схему: мобильное устройство отправляет запрос на IP-адрес ноутбука, где запущена 1С, компонента перехватывает этот запрос, передает его в код 1С для обработки, после чего мы формируем ответ и отправляем его обратно устройству.
Одной из главных проблем, с которой сталкиваются разработчики при переносе кода с 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С всегда будет отзывчивой.ВвестиСтроку с таймаутом или использование компоненты 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 открывает для «старой доброй семерки» двери в мир современных интеграций, позволяя не отказываться от отлаженных годами систем учета в пользу громоздких новых конфигураций там, где важна скорость и автономность.