1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-11-25 22:12:29 +02:00
Files
OpenIntegrations/XML/CommonModules/OPI_TCP/Ext/Module.bsl
Vitaly the Alpaca (bot) cdef2d02ab Main build (Jenkins)
2025-10-21 21:43:05 +03:00

310 lines
17 KiB
Plaintext

// OneScript: ./OInt/core/Modules/OPI_TCP.os
// Lib: TCP
// CLI: tcp
// Keywords: tcp
// MIT License
// Copyright (c) 2023-2025 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
// BSLLS:LatinAndCyrillicSymbolInWord-off
// BSLLS:IncorrectLineBreak-off
// BSLLS:NumberOfOptionalParams-off
// BSLLS:UsingServiceTag-off
// BSLLS:LineLength-off
// BSLLS:UsingSynchronousCalls-off
// BSLLS:MagicNumber-off
//@skip-check module-structure-top-region
//@skip-check module-structure-method-in-regions
//@skip-check wrong-string-literal-content
//@skip-check method-too-many-params
#Область ПрограммныйИнтерфейс
#Область МетодыКлиента
// Открыть соединение !NOCLI
// Создает TCP соединение
//
// Параметры:
// Адрес - Строка - Адрес и порт для подключения - address
// Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение, Произвольный - Возвращает объект TCP клиента при успешном подключении или информацию об ошибке
Функция ОткрытьСоединение(Знач Адрес, Знач Tls = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Адрес);
OPI_Инструменты.ВернутьУправляющиеПоследовательности(Адрес);
Домен = OPI_Инструменты.ПолучитьДомен(Адрес);
TCPКлиент = OPI_Компоненты.ПолучитьКомпоненту("TCPClient");
Успех = TCPКлиент.SetAddress(Адрес, Домен);
Если Не Успех Тогда
Возврат ПолучитьПоследнююОшибку(TCPКлиент);
КонецЕсли;
Tls = OPI_Компоненты.УстановитьTls(TCPКлиент, Tls);
Если Не OPI_Инструменты.ПолучитьИли(Tls, "result", Ложь) Тогда
Возврат Tls;
КонецЕсли;
Успех = TCPКлиент.Connect();
Если Не Успех Тогда
Возврат ПолучитьПоследнююОшибку(TCPКлиент);
КонецЕсли;
Возврат TCPКлиент;
КонецФункции
// Закрыть соединение !NOCLI
// Явно закрывает созданное ранее соединение
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
//
// Возвращаемое значение:
// Булево - всегда возвращает Истина
Функция ЗакрытьСоединение(Знач Соединение) Экспорт
Возврат Соединение.Disconnect();
КонецФункции
// Прочитать двоичные данные !NOCLI
// Читает данные из указанного соединения
//
// Примечание:
// При работе с бесконечным потоком входящих данных обязательно указание параметра МаксимальныйРазмер, так как^^
// бесконечное получение данных может привести к зависанию
// При закрытии соединения, ошибке или обнаружении EOF чтение завершается в любом случае
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// МаксимальныйРазмер - Число - Максимальный размер данных (байт). 0 > без ограничений - size
// Маркер - Строка, ДвоичныеДанные - Маркер конца сообщения. Пусто > без маркера - marker
// Таймаут - Число - Таймаут ожидания данных (мс). 0 > без ограничений - timeout
//
// Возвращаемое значение:
// ДвоичныеДанные - Полученные данные
Функция ПрочитатьДвоичныеДанные(Знач Соединение
, Знач МаксимальныйРазмер = 0
, Знач Маркер = ""
, Знач Таймаут = 5000) Экспорт
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
OPI_ПреобразованиеТипов.ПолучитьЧисло(МаксимальныйРазмер);
Если ТипЗнч(Маркер) = Тип("Строка") Тогда
Маркер = ПолучитьДвоичныеДанныеИзСтроки(Маркер);
Иначе
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Маркер);
КонецЕсли;
Данные = Соединение.Read(МаксимальныйРазмер, Маркер, Таймаут);
Возврат Данные;
КонецФункции
// Прочитать строку !NOCLI
// Читает данные из указанного соединения в виде строки
//
// Примечание:
// При закрытии соединения, ошибке или обнаружении EOF чтение завершается в любом случае
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// Кодировка - Строка - Кодировка преобразования данных в строку - enc
// Маркер - Строка, ДвоичныеДанные - Маркер конца сообщения. Пусто > без маркера - marker
// Таймаут - Число - Таймаут ожидания данных (мс). 0 > без ограничений - timeout
//
// Возвращаемое значение:
// Строка - Полученные данные в виде строки
Функция ПрочитатьСтроку(Знач Соединение
, Знач Кодировка = "UTF-8"
, Знач Маркер = ""
, Знач Таймаут = 5000) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Кодировка);
Данные = ПрочитатьДвоичныеДанные(Соединение, , Маркер, Таймаут);
Данные = ПолучитьСтрокуИзДвоичныхДанных(Данные, Кодировка);
Возврат Данные;
КонецФункции
// Отправить двоичные данные !NOCLI
// Отправляет двоичные данные через указанное соединение
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// Данные - ДвоичныеДанные - Данные для отправки - data
// Таймаут - Число - Таймаут ожидания записи (мс). 0 > без ограничений - timeout
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения
Функция ОтправитьДвоичныеДанные(Знач Соединение, Знач Данные, Знач Таймаут = 5000) Экспорт
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Данные);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
Результат = Соединение.Send(Данные, Таймаут);
Возврат Результат;
КонецФункции
// Отправить строку !NOCLI
// Отправляет данные в виде строки через указанное соединение
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// Данные - Строка - Данные для отправки в виде строки - data
// Кодировка - Строка - Кодировка для записи исходящей строки в поток - enc
// Таймаут - Число - Таймаут ожидания записи (мс). 0 > без ограничений - timeout
//
// Возвращаемое значение:
// Булево - Признак успешного выполнения
Функция ОтправитьСтроку(Знач Соединение, Знач Данные, Знач Кодировка = "UTF-8", Знач Таймаут = 5000) Экспорт
OPI_ПреобразованиеТипов.ПолучитьСтроку(Данные);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Кодировка);
ДанныеДД = ПолучитьДвоичныеДанныеИзСтроки(Данные, Кодировка);
Результат = ОтправитьДвоичныеДанные(Соединение, ДанныеДД, Таймаут);
Возврат Результат;
КонецФункции
// Обработать запрос
// Отправляет одиночный запрос на указанный адрес и получает ответ, используя стандартные настройки
//
// Параметры:
// Адрес - Строка - Адрес и порт для подключения - address
// Данные - Строка, ДвоичныеДанные - Данные или текст для отправки - data
// ОтветСтрокой - Булево - Признак получения ответа как строки - string
// Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls
//
// Возвращаемое значение:
// ДвоичныеДанные, Строка - Ответ на запрос или информация об ошибке
Функция ОбработатьЗапрос(Знач Адрес, Знач Данные = "", Знач ОтветСтрокой = Истина, Знач Tls = "") Экспорт
OPI_ПреобразованиеТипов.ПолучитьДвоичныеДанные(Данные, Истина, Ложь);
OPI_ПреобразованиеТипов.ПолучитьБулево(ОтветСтрокой);
Соединение = ОткрытьСоединение(Адрес, Tls);
Если Не OPI_Компоненты.ЭтоКомпонента(Соединение) Тогда
Возврат Соединение;
КонецЕсли;
Результат = ОтправитьДвоичныеДанные(Соединение, Данные);
Если Результат Тогда
Ответ = ПрочитатьДвоичныеДанные(Соединение, , Символы.ПС);
Если Не ЗначениеЗаполнено(Ответ) Тогда
Ошибка = ПолучитьПоследнююОшибку(Соединение);
Если ЗначениеЗаполнено(Ошибка) Тогда
Ответ = OPI_Инструменты.JSONСтрокой(Ошибка);
Ответ = ПолучитьДвоичныеДанныеИзСтроки(Ответ);
КонецЕсли;
КонецЕсли;
Ответ = ?(ОтветСтрокой, ПолучитьСтрокуИзДвоичныхДанных(Ответ), Ответ);
Иначе
Ответ = ПолучитьПоследнююОшибку(Соединение);
Ответ = ?(ЗначениеЗаполнено(Ответ), OPI_Инструменты.JSONСтрокой(Ответ), "OPI: Не удалось отправить сообщение");
Ответ = ?(ОтветСтрокой, Ответ, ПолучитьДвоичныеДанныеИзСтроки(Ответ));
КонецЕсли;
ЗакрытьСоединение(Соединение);
Возврат Ответ;
КонецФункции
// Получить последнюю ошибку !NOCLI
// Получает информацию о последней ошибке в соединении
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение, Неопределено - Информация об ошибке или неопределено, если ошибки нет
Функция ПолучитьПоследнююОшибку(Знач Соединение) Экспорт
Результат = Соединение.GetLastError();
Если ЗначениеЗаполнено(Результат) Тогда
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получить настройки TLS
// Формирует настройки для использования TLS при выполнении запросов
//
// Примечание:
// Настройки Tls могут быть установлены только в момент создания соединения: явного, при использовании функции `ОткрытьСоединение`^^
// или неявного, при передаче строки подключения в метод `ОбработатьЗапрос`
//
// Параметры:
// ОтключитьПроверкуСертификатов - Булево - Позволяет работать с некорретными сертификатами, в т.ч. самоподписанными - trust
// ПутьКСертификату - Строка - Путь к корневому PEM файлу сертификата, если его нет в системном хранилище - cert
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Структура настроек TLS соединения
Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов, Знач ПутьКСертификату = "") Экспорт
Возврат OPI_Компоненты.ПолучитьНастройкиTls(ОтключитьПроверкуСертификатов, ПутьКСертификату);
КонецФункции
#КонецОбласти
#КонецОбласти