Как программно проверить подключение к интернету из конфигурации 1С 8.3?

Программист 1С v8.3 (Управляемые формы)
← На главную

Здравствуйте, уважаемые коллеги! Сегодня мы с вами глубоко погрузимся в такую актуальную задачу, как программная проверка наличия подключения к интернету непосредственно из конфигурации 1С 8.3. Этот вопрос часто возникает у разработчиков, когда необходимо обеспечить надежную работу функционала, взаимодействующего с внешними веб-сервисами, почтой, FTP или другими интернет-ресурсами. Мы проанализируем различные подходы, рассмотрим примеры кода и обсудим нюансы каждого метода.

Важно понимать, что "наличие интернета" — это не всегда однозначное понятие. Для одной задачи это может означать доступ к определенному веб-сервису по протоколу HTTP/HTTPS, для другой — возможность отправить электронное письмо по SMTP, а для третьей — просто базовую сетевую связность до удаленного узла. Поэтому универсального метода, который бы гарантировал доступность абсолютно всех интернет-сервисов, не существует. Мы должны будем определить, какой именно аспект подключения нас интересует, и выбрать наиболее подходящий инструмент.

Подход 1: Предполагаем наличие интернета и обрабатываем ошибки

Один из самых надежных и часто рекомендуемых подходов заключается в том, чтобы не пытаться заранее проверить интернет, а сразу выполнять требуемое действие, работающее с интернетом. Если интернет-соединения нет или возникли другие проблемы с доступом к целевому ресурсу, мы просто обрабатываем возникшие ошибки.

  1. Преимущества:
    • Этот метод проверяет реальную доступность именно того сервиса, который вам необходим (например, конкретного веб-сервиса, почтового сервера), а не абстрактное "наличие интернета".
    • Позволяет предоставить пользователю максимально точную информацию о том, что именно пошло не так (например, "Не удалось подключиться к серверу Y", а не просто "Нет интернета").
    • Избегаем лишних предварительных проверок, которые могут быть медленными или некорректными.
  2. Недостатки:
    • Требует тщательной и подробной обработки исключений в коде.
    • Может быть нежелательным, если операция с интернетом является очень "тяжелой" или дорогой, и мы хотели бы избежать ее выполнения в случае отсутствия связи.

Для реализации этого подхода мы активно используем конструкцию Попытка...Исключение...КонецПопытки, которая позволяет перехватывать ошибки, возникающие при выполнении сетевых операций. В блоке Исключение мы можем проанализировать тип ошибки и уведомить пользователя или предпринять альтернативные действия.


Попытка
    // Здесь размещаем код, который работает с интернет-ресурсами
    // Например, отправка HTTP-запроса, получение данных с сервера и т.п.
    // ...
    Сообщить("Операция с интернет-ресурсом успешно выполнена!");
Исключение
    Сообщить("Ошибка при работе с интернет-ресурсом: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    // Дополнительная логика обработки ошибки, например, запись в лог,
    // повторная попытка через некоторое время, отключение функционала.
КонецПопытки;

Подход 2: Проверка доступности HTTP-ресурса с помощью нативных средств 1С (HTTPСоединение и HTTPЗапрос)

Наиболее распространенный и рекомендуемый способ для проверки доступности веб-ресурсов в 1С — это попытка установить HTTP-соединение с известным и стабильным интернет-ресурсом. Для этого мы будем использовать встроенные объекты 1С: HTTPСоединение и HTTPЗапрос. Для отладки таких параметров подключения и проверки ответов сервера удобно применять консоль HTTP-запросов для управляемых форм.

  1. Создание соединения:

    Мы создаем объект HTTPСоединение, указывая адрес сервера. В качестве адреса можно использовать известные стабильные ресурсы, такие как "ya.ru", "google.com", или специализированный сервер вашей организации, доступность которого гарантирована.

    
    Сервер = "ya.ru"; // Или "google.com", "api.myservice.com"
    Порт = 80;        // Для HTTP, для HTTPS обычно 443
    ИспользоватьHTTPS = Ложь; // Для ya.ru достаточно HTTP для простой проверки
            
    Попытка
        Соединение = Новый HTTPСоединение(Сервер, Порт, , , , , ИспользоватьHTTPS);
        Сообщить("Объект HTTPСоединение создан.");
    Исключение
        Сообщить("Не удалось создать HTTPСоединение. Возможно, нет базового сетевого подключения.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
    

    Обратите внимание на параметры конструктора: Сервер (строка), Порт (число), ИспользоватьHTTPS (булево). Для HTTPS-соединений Порт по умолчанию 443, для HTTP — 80.

  2. Создание и выполнение запроса:

    Далее мы создаем пустой объект HTTPЗапрос и пытаемся получить какой-либо ресурс (например, корневую страницу "/"). Метод Получить() объекта HTTPСоединение выполняет запрос и возвращает объект HTTPОтвет.

    
    Запрос = Новый HTTPЗапрос("/"); // Запрос корневой страницы
    Ответ = Неопределено;
            
    Попытка
        Ответ = Соединение.Получить(Запрос);
    Исключение
        Сообщить("Ошибка при получении HTTP-ответа. Возможно, нет доступа к интернет-ресурсу.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
    
  3. Анализ ответа:

    Если запрос прошел без исключений, это еще не гарантия полного успеха. Мы должны проанализировать статус ответа HTTP. Код статуса 200 (OK) обычно означает успешное получение ресурса. Другие коды могут указывать на перенаправления (3xx), ошибки на стороне клиента (4xx) или сервера (5xx).

    
    Если Ответ <> Неопределено Тогда
        Если Ответ.КодСостояния = 200 Тогда
            Сообщить("Есть подключение к интернету через HTTPСоединение к " + Сервер + ". Статус: " + Ответ.КодСостояния);
            Возврат Истина;
        Иначе
            Сообщить("HTTP-запрос к " + Сервер + " завершился с кодом состояния: " + Ответ.КодСостояния + ". Возможно, ресурс недоступен или проблемы с сетью.", СтатусСообщения.Важное);
            Возврат Ложь;
        КонецЕсли;
    Иначе
        Сообщить("Не получен HTTP-ответ. Сбой на более низком уровне.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецЕсли;
    

    Собираем все воедино в виде функции:

    
    Функция ПроверитьПодключениеКИнтернетуHTTP(СерверДляПроверки = "ya.ru") Экспорт
                
        Перем Соединение, Запрос, Ответ;
                
        Попытка
            Соединение = Новый HTTPСоединение(СерверДляПроверки, 80); // Используем HTTP для простоты, если не нужен HTTPS
            Запрос = Новый HTTPЗапрос("/");
                    
            Ответ = Соединение.Получить(Запрос);
                    
            Если Ответ <> Неопределено Тогда
                Если Ответ.КодСостояния = 200 Тогда
                    Возврат Истина; // Подключение есть, ресурс доступен
                Иначе
                    Сообщить("HTTP-запрос к " + СерверДляПроверки + " вернул код: " + Ответ.КодСостояния, СтатусСообщения.Информация);
                    Возврат Ложь;
                КонецЕсли;
            Иначе
                Сообщить("HTTP-ответ не был получен от " + СерверДляПроверки, СтатусСообщения.Информация);
                Возврат Ложь;
            КонецЕсли;
        Исключение
            Сообщить("Ошибка при попытке подключения к " + СерверДляПроверки + ": " + ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат Ложь; // Ошибка означает отсутствие подключения или проблемы с сетью
        КонецПопытки;
                
    КонецФункции
            
    // Пример использования:
    // Если ПроверитьПодключениеКИнтернетуHTTP() Тогда
    //    Сообщить("Есть подключение к интернету (через ya.ru)");
    // Иначе
    //    Сообщить("Нет подключения к интернету (через ya.ru)");
    // КонецЕсли;
    
  4. Преимущества:
    • Является нативным для 1С, не требует использования внешних COM-объектов.
    • Позволяет проверить доступность конкретного веб-ресурса.
    • Относительно прост в реализации.
  5. Недостатки:
    • Проверка доступности одного ресурса не гарантирует доступность всех остальных интернет-сервисов (например, почты или FTP).
    • Может быть заблокирован прокси-сервером или фаерволом, даже если интернет в целом есть для других приложений.
    • Некоторые "стабильные" ресурсы могут быть временно недоступны (как показал случай с Яндекс). Мы должны учитывать это и, возможно, использовать несколько тестовых адресов.

Подход 3: Использование COM-объекта WinHttp.WinHttpRequest для HTTP-запросов

Этот метод, похожий на InternetAttemptConnect из FoxPro, позволяет выполнять HTTP-запросы через COM-объект WinHttp.WinHttpRequest.5.1, который является частью операционной системы Windows. Он предоставляет более гибкий контроль над HTTP-запросами, чем стандартные средства 1С.

  1. Создание COM-объекта:

    Мы создаем экземпляр COM-объекта WinHttp.WinHttpRequest.5.1.

    
    WinHttp = Неопределено;
    Попытка
        WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    Исключение
        Сообщить("Ошибка создания COM-объекта 'WinHttp.WinHttpRequest.5.1'. Возможно, не зарегистрирован или отсутствует в системе.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
    
  2. Выполнение запроса:

    Используем методы Open() для подготовки запроса и Send() для его выполнения. Мы можем указать тайм-аут для операции, чтобы избежать длительного зависания.

    
    URLДляПроверки = "http://www.ya.ru"; // Или другой стабильный ресурс
            
    Попытка
        WinHttp.Open("GET", URLДляПроверки, Ложь); // GET-запрос, синхронный (Ложь)
        WinHttp.SetRequestHeader("User-Agent", "1C_HTTP_Checker"); // Опционально: установить User-Agent
        WinHttp.Send();
    Исключение
        Сообщить("Ошибка при отправке HTTP-запроса через WinHttp: " + ОписаниеОшибки(), СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
    
  3. Анализ ответа:

    После отправки запроса мы можем получить статус ответа через свойство WinHttp.Status.

    
    Если WinHttp <> Неопределено И WinHttp.Status = 200 Тогда
        Сообщить("Есть подключение к интернету через WinHttp к " + URLДляПроверки + ". Статус: " + WinHttp.Status);
        Возврат Истина;
    ИначеЕсли WinHttp <> Неопределено Тогда
        Сообщить("HTTP-запрос через WinHttp к " + URLДляПроверки + " завершился с кодом состояния: " + WinHttp.Status + ". Текст: " + WinHttp.StatusText, СтатусСообщения.Важное);
        Возврат Ложь;
    Иначе
        Сообщить("Объект WinHttp не инициализирован.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецЕсли;
    
  4. Особенности и дополнительные возможности:
    • Настройка прокси: Мы можем настроить прокси-сервер с помощью метода WinHttp.SetProxy().
    • HTTPS и сертификаты: Для HTTPS-соединений, если возникают ошибки сертификатов (например, "The certificate authority is invalid or incorrect"), можно временно игнорировать ошибки с помощью WinHttp.Option(4)=13056. Однако мы настоятельно не рекомендуем использовать этот подход в продакшн-системах из-за серьезных рисков безопасности, так как это отключает проверку подлинности сервера.
    • Тайм-аут: Мы можем установить тайм-аут для операций с помощью WinHttp.SetTimeouts().

    Пример функции с WinHttp.WinHttpRequest:

    
    Функция ПроверитьПодключениеКИнтернетуWinHttp(URLДляПроверки = "http://www.ya.ru", Таймаут = 5000) Экспорт // Таймаут в миллисекундах
                
        Перем WinHttp;
                
        Попытка
            WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
        Исключение
            Сообщить("Не удалось создать COM-объект WinHttp.WinHttpRequest.5.1. " + ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат Ложь;
        КонецПопытки;
                
        Попытка
            WinHttp.Open("GET", URLДляПроверки, Ложь); // Метод GET, синхронный запрос
            WinHttp.SetTimeouts(Таймаут, Таймаут, Таймаут, Таймаут); // Resolve, Connect, Send, Receive timeouts
            // WinHttp.Option(4) = 13056; // Не рекомендуется: Игнорировать ошибки SSL
            WinHttp.Send();
                    
            Если WinHttp.Status = 200 Тогда
                Возврат Истина; // Подключение есть, ресурс доступен
            Иначе
                Сообщить("Запрос к " + URLДляПроверки + " вернул код: " + WinHttp.Status + " (" + WinHttp.StatusText + ")", СтатусСообщения.Информация);
                Возврат Ложь;
            КонецЕсли;
        Исключение
            Сообщить("Ошибка при запросе к " + URLДляПроверки + " через WinHttp: " + ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат Ложь; // Ошибка означает отсутствие подключения или проблемы с сетью
        КонецПопытки;
                
    КонецФункции
            
    // Пример использования:
    // Если ПроверитьПодключениеКИнтернетуWinHttp() Тогда
    //    Сообщить("Есть подключение к интернету (через WinHttp)");
    // Иначе
    //    Сообщить("Нет подключения к интернету (через WinHttp)");
    // КонецЕсли;
    
  5. Преимущества:
    • Предоставляет более гибкий контроль над HTTP-запросами, чем стандартные средства 1С.
    • Позволяет настраивать прокси и тайм-ауты.
  6. Недостатки:
    • Зависит от наличия и корректной регистрации COM-объекта в операционной системе Windows.
    • Как и HTTPСоединение, проверяет доступность конкретного веб-ресурса, а не "интернета" в целом.

Подход 4: Проверка сетевой доступности узла с помощью ping и WScript.Shell

Метод, предложенный в обсуждении, с использованием COM-объекта WScript.Shell для вызова системной команды ping является рабочим способом проверки базовой сетевой доступности узла. Этот способ проверяет, отвечает ли удаленный хост на ICMP-запросы.

  1. Создание COM-объекта:

    Мы создаем объект WScript.Shell.

    
    wss = Неопределено;
    Попытка
        wss = Новый COMОбъект("WScript.Shell");
    Исключение
        Сообщить("Ошибка создания COM-объекта 'WScript.Shell'. Возможно, не зарегистрирован или отсутствует в системе.", СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
    
  2. Выполнение команды ping:

    Мы используем метод Run() объекта WScript.Shell для выполнения команды ping. Параметры ping: -w 1500 устанавливает тайм-аут ожидания ответа в 1500 мс (1.5 секунды), -n 1 отправляет только один пакет.

    
    IP_или_Домен = "8.8.8.8"; // Можно использовать IP-адрес Google DNS или домен "ya.ru"
    КомандаПинг = "ping -w 1500 -n 1 " + IP_или_Домен;
            
    РезультатВыполнения = 0;
    Попытка
        // wss.Run(Команда, ОкноЗапуска, ОжидатьЗавершения)
        // 0 - скрытый запуск, Истина - ожидать завершения
        РезультатВыполнения = wss.Run(КомандаПинг, 0, Истина);
    Исключение
        Сообщить("Ошибка при выполнении команды ping через WScript.Shell: " + ОписаниеОшибки(), СтатусСообщения.Важное);
        Возврат Ложь;
    КонецПопытки;
            
    // Команда ping возвращает 0 при успешном выполнении
    // (т.е., если узел доступен и ответил на пинг)
    ЕстьИнет = (РезультатВыполнения = 0);
            
    Если ЕстьИнет Тогда
        Сообщить("Есть подключение к интернету (через ping к " + IP_или_Домен + ")");
        Возврат Истина;
    Иначе
        Сообщить("Нет подключения к интернету (через ping к " + IP_или_Домен + "). Код возврата: " + РезультатВыполнения, СтатусСообщения.Важное);
        Возврат Ложь;
    КонецЕсли;
    

    Собираем все воедино в виде функции:

    
    Функция ПроверитьПодключениеКИнтернетуPing(IP_или_Домен = "8.8.8.8") Экспорт // Google DNS
                
        Перем wss;
                
        Попытка
            wss = Новый COMОбъект("WScript.Shell");
        Исключение
            Сообщить("Не удалось создать COM-объект WScript.Shell. " + ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат Ложь;
        КонецПопытки;
                
        Перем РезультатВыполнения;
        КомандаПинг = "ping -w 1500 -n 1 " + IP_или_Домен;
                
        Попытка
            // wss.Run(Команда, ОкноЗапуска, ОжидатьЗавершения)
            // 0 - скрытый запуск, Истина - ожидать завершения
            РезультатВыполнения = wss.Run(КомандаПинг, 0, Истина);
        Исключение
            Сообщить("Ошибка при выполнении команды ping: " + ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат Ложь;
        КонецПопытки;
                
        // Команда ping возвращает 0 при успешном выполнении
        // (т.е., если узел доступен и ответил на пинг)
        Возврат (РезультатВыполнения = 0);
                
    КонецФункции
            
    // Пример использования:
    // Если ПроверитьПодключениеКИнтернетуPing() Тогда
    //    Сообщить("Есть подключение к интернету (через ping)");
    // Иначе
    //    Сообщить("Нет подключения к интернету (через ping)");
    // КонецЕсли;
    
  3. Преимущества:
    • Проверяет базовую сетевую связность до узла, что может быть полезно для диагностики общей проблемы с сетью.
    • Сравнительно прост в реализации.
  4. Недостатки:
    • Команда ping может быть заблокирована на фаерволе целевого сервера или промежуточных сетевых устройств, даже если HTTP-доступ к ресурсу возможен. В таком случае, ping будет показывать отсутствие связи, хотя интернет есть.
    • Зависит от наличия и корректной работы WScript.Shell и утилиты ping в операционной системе.
    • Не является индикатором доступности конкретного сервиса (например, веб-сайта или почты), а только сетевого узла.

Общие рекомендации и важные нюансы

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

  1. Определите цель проверки:

    Для чего именно вам нужно проверить интернет? Если вам требуется доступ к веб-сервису, то используйте методы, основанные на HTTP (HTTPСоединение или WinHttp.WinHttpRequest). Если нужно проверить доступность почтового сервера, попробуйте установить соединение по соответствующим протоколам (SMTP, POP3, IMAP). Общая проверка ping может быть полезна для диагностики базовых проблем со связью, но она не гарантирует доступности высокоуровневых сервисов.

  2. Проверяйте конкретный ресурс:

    Если в вашей системе есть жесткая зависимость от определенного интернет-ресурса (например, внешний API), то наилучшим решением будет проверка доступности именно этого ресурса, а не абстрактного "интернета". Это даст наиболее точную картину. Используйте адреса, которые точно должны быть доступны и стабильны. Для этих целей можно использовать специализированные решения, такие как утилита для проверки доступности вебхуков Битрикс24 из 1С, которая работает на Windows и Linux без использования COM-объектов.

  3. Используйте асинхронные методы:

    Проверка интернет-соединения может занимать некоторое время. Чтобы не блокировать пользовательский интерфейс 1С и обеспечить лучшую отзывчивость программы, мы рекомендуем по возможности использовать асинхронные вызовы или выполнять проверку в фоновом задании (например, через ФоновыеЗадания или на стороне сервера).

    
    // Пример асинхронного вызова на клиенте (управляемые формы)
    // Создаем обработчик ожидания
    // Подключаем его к процедуре проверки
    // ПриОтключенииОжидания() анализируем результат
    
  4. Всегда обрабатывайте исключения:

    Вне зависимости от выбранного метода, мы должны всегда предусматривать обработку исключений с помощью конструкции Попытка...Исключение...КонецПопытки. Это позволит программе корректно реагировать на проблемы и информировать пользователя или администратора о причинах сбоя, а не просто "падать".

  5. Учитывайте прокси-серверы и фаерволы:

    Очень часто проблемы с доступом к интернету из 1С связаны с настройками корпоративных прокси-серверов или фаерволов. Они могут блокировать определенные порты, протоколы или домены. Убедитесь, что ваша 1С-конфигурация настроена для работы через прокси, если это необходимо. Для HTTPСоединение можно использовать Соединение.УстановитьПрокси(АдресПрокси, ПортПрокси, ПользовательПрокси, ПарольПрокси);.

  6. Специализированные подсистемы 1С:Фреш и диагностики качества соединения:

    Для решений, работающих в облачной модели 1С:Фреш, существуют встроенные механизмы диагностики качества соединения. Эти инструменты выполняют быстрые или длительные тесты и выводят информацию для анализа специалистами. Если вы работаете с 1С:Фреш, ознакомьтесь с их документацией по диагностике.

  7. Проверка доступности внешних ресурсов для 1С-Отчетности:

    Для работы таких сервисов, как "1С-Отчетность", требуется обеспечить доступ к определенным внешним ресурсам по конкретным протоколам и портам (например, HTTP 80, HTTPS 443, SMTP 465/25, POP3 110/995). Это подчеркивает, что "интернет" для 1С часто означает доступность конкретных сервисов по определенным адресам, а не просто наличие общего соединения.

Таким образом, мы видим, что не существует единого "святого грааля" для проверки подключения к интернету в 1С 8.3. Мы должны тщательно анализировать свои потребности, выбирать наиболее подходящий метод или их комбинацию, и всегда предусматривать robustную обработку ошибок. Надеемся, что этот подробный разбор поможет вам в вашей работе!

← На главную