При разработке механизмов автоматизации в 1С:Предприятие часто возникает ситуация, когда код, идеально работающий в ручном режиме (через консоль отчетов или обработку), внезапно «падает» с ошибкой при запуске в виде регламентного задания. Одной из самых коварных ошибок является: «Ошибка работы с Интернет: Не могу установить соединение» при вызове метода Получить объекта HTTPСоединение. Проанализируем, почему это происходит и как настроить сервер для стабильной работы.
Выясним основную причину: когда вы запускаете загрузку курсов валют интерактивно, код выполняется в контексте вашего сеанса Windows под вашей учетной записью. Фоновое задание же выполняется на стороне сервера 1С:Предприятия под управлением процесса rphost.exe. Этот процесс запускается от имени специального системного пользователя (обычно это USR1CV8 или LOCAL SERVICE).
Рассмотрим, к каким последствиям это приводит:
ЗащищенноеСоединениеOpenSSL, сервер должен доверять сертификату сайта. Сертификаты, установленные для вашего пользователя, могут быть недоступны для службы сервера.Получить скачивает файл во временный каталог. Если у пользователя USR1CV8 нет прав на запись в системную папку Temp, возникнет ошибка.Если ваша корпоративная сеть работает через прокси-сервер, фоновое задание «не знает», как через него пройти. Проанализируем два способа решения этой проблемы.
Способ 1: Использование файла inetcfg.xml. Вы можете жестко прописать настройки прокси для всего сервера 1С. Для этого в папке с установленной платформой (например, C:\Program Files\1cv8\conf) нужно создать или отредактировать файл inetcfg.xml, указав в нем параметры подключения.
Способ 2: Явное указание прокси в коде. Это более гибкий вариант. Разберем пример кода, который определяет настройки прокси динамически:
Функция ПолучитьНастроенноеСоединение(СерверИсточник)
// Попытаемся получить системные настройки прокси
Прокси = НужнаяНастройкаПрокси();
// Если автоматика не сработала, создаем объект вручную
// Прокси = Новый HTTPПрокси("192.168.1.1", 8080);
// Прокси.Пользователь = "proxy_user";
// Прокси.Пароль = "proxy_password";
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Передаем объект Прокси в конструктор соединения
HTTP = Новый HTTPСоединение(СерверИсточник, 443, , , Прокси, , Защита);
Возврат HTTP;
КонецФункции
Современные ресурсы (например, cbr.ru) работают по протоколу HTTPS. Рассмотрим ситуацию, когда ошибка «Не могу установить соединение» возникает из-за недоверия к SSL-сертификату. В сеансе пользователя Windows может автоматически скачивать корневые сертификаты, а серверная служба лишена этой возможности.
Чтобы решить эту проблему, выполним следующие шаги:
Также важно убедиться, что ваша операционная система поддерживает протоколы TLS 1.2 и выше. На старых версиях Windows Server (например, 2008 R2) может потребоваться установка обновлений или правка реестра для включения этих протоколов, иначе HTTPСоединение просто не сможет согласовать метод шифрования.
Проанализируем код, представленный в вопросе автора. В нем содержится типичная ошибка переопределения переменной:
Если ТипЗнч(HTTP) <> Тип("HTTPСоединение") Тогда
HTTP = Новый HTTPСоединение(СерверИсточник); // Ошибка: создание без SSL
HTTP = Новый HTTPСоединение(СерверИсточник, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL()); // Перезапись
КонецЕсли;
Первая строка инициализации здесь абсолютно лишняя, так как во второй строке объект HTTP полностью перезаписывается. Кроме того, если вы используете порт 443, обязательно нужно использовать ЗащищенноеСоединениеOpenSSL. Посмотрим на исправленный и оптимизированный вариант функции:
Функция ЗапроситьФайлыССервера(СерверИсточник, СтрокаПараметра, ПутьКФайлу) Экспорт
// Настраиваем защищенное соединение для HTTPS (порт 443)
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Инициализируем соединение один раз со всеми параметрами
HTTP = Новый HTTPСоединение(СерверИсточник, 443, , , , 30, Защита);
Попытка
// Выполняем запрос
HTTP.Получить(СтрокаПараметра, ПутьКФайлу);
Возврат Истина;
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("Загрузка курсов", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при получении данных: " + КраткоеПредставлениеОшибки(Инфо));
Возврат Ложь;
КонецПопытки;
КонецФункции
Часто проблема кроется не в сети, а в методе Получить(Параметры, ИмяВходящегоФайла). В фоновом задании переменная ИмяВходящегоФайла должна содержать путь, доступный серверу 1С. Если вы передаете путь типа "C:\Users\Admin\Documents\rates.xml", сервер под пользователем USR1CV8 не сможет туда записать файл.
Рекомендуется использовать функцию ПолучитьИмяВременногоФайла(), которая гарантированно вернет путь к папке, на которую у службы 1С есть права:
ИмяФайла = ПолучитьИмяВременногоФайла("xml");
Если ЗапроситьФайлыССервера("cbr.ru", "/scripts/XML_daily.asp", ИмяФайла) Тогда
// Обработка файла
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
// ... логика парсинга ...
Чтение.Закрыть();
УдалитьФайлы(ИмяФайла); // Не забываем чистить за собой
КонецЕсли;
Разберем ситуацию с блокировками на уровне сети. Бывает так, что системный администратор разрешил доступ в интернет для пользователей, но ограничил его для серверных процессов. Процесс rphost.exe (рабочий процесс сервера 1С) может быть заблокирован брандмауэром или антивирусом.
Для диагностики попробуйте:
rphost.exe в исключения антивирусного ПО.ping cbr.ru из командной строки сервера. Если имя не разрешается, значит проблема в настройках DNS сервера.Подводя итог, можно сказать, что решение проблемы с фоновой загрузкой всегда лежит в плоскости настройки прав и окружения пользователя, под которым работает сервер 1С. Тщательная проверка прокси, сертификатов и прав на файловую систему в 99% случаев позволяет устранить ошибку «Не могу установить соединение».