1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2024-12-27 02:43:54 +02:00

Доработка компоненты TCP

This commit is contained in:
Anton Titovets 2024-12-13 23:10:13 +03:00
parent cb457679ae
commit 90969ea2f8
11 changed files with 6195 additions and 6158 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -45,40 +45,47 @@ pub fn send(connection: &mut Connection, data: Vec<u8>, timeout_ms: i32) -> bool
/// Считывает данные
pub fn receive(
connection: &mut Connection,
buffer_size: i32,
timeout_ms: i32,
max_attempts: i32,
max_data_size: i32,
max_duration_s: f64,
) -> Vec<u8> {
const BUFFER_SIZE: usize = 4096; // Фиксированный размер буфера
let mut result = Vec::new();
let mut buffer = vec![0u8; buffer_size as usize];
let start_time = Instant::now();
let mut buffer = vec![0u8; BUFFER_SIZE];
let mut attempts = 0;
// Если max_duration_ms > 0, устанавливаем таймаут только если он не установлен
if max_duration_s > 0.0 {
// Устанавливаем таймаут для чтения
let timeout = Duration::from_millis(timeout_ms as u64);
match connection {
Connection::Tcp(stream) => {
stream.set_read_timeout(Some(Duration::from_millis(timeout_ms as u64))).ok();
stream.set_read_timeout(Some(timeout)).ok();
}
Connection::Tls(stream) => {
stream.get_ref().set_read_timeout(Some(Duration::from_millis(timeout_ms as u64))).ok();
}
stream.get_ref().set_read_timeout(Some(timeout)).ok();
}
}
loop {
// Проверяем ограничения, если они заданы
if (max_data_size > 0 && result.len() >= max_data_size as usize) ||
(max_duration_s > 0.0 && start_time.elapsed() > Duration::from_secs_f64(max_duration_s)) {
// Завершаем цикл, если превышен лимит данных
if max_data_size > 0 && result.len() >= max_data_size as usize {
break;
}
match connection.read(&mut buffer) {
Ok(0) => break, // EOF - конец данных
Ok(size) => result.extend_from_slice(&buffer[..size]),
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, // Таймаут
Err(_) => break, // Любая другая ошибка
Ok(0) => break, // Конец данных (EOF)
Ok(size) => {
result.extend_from_slice(&buffer[..size]);
attempts = 0; // Сбрасываем счетчик попыток при успешном чтении
}
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
attempts += 1;
if attempts >= max_attempts {
break; // Превышено число попыток ожидания
}
continue; // Пробуем снова
}
Err(_) => break // Любая другая ошибка
}
}

View File

@ -22,7 +22,7 @@ pub fn get_params_amount(num: usize) -> usize {
match num {
0 => 0,
1 => 0,
2 => 4,
2 => 3,
3 => 2,
_ => 0,
}
@ -41,13 +41,13 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
},
2 => {
let size = params[0].get_i32().unwrap_or(0);
let timeout = params[1].get_i32().unwrap_or(0);
let timeout = params[0].get_i32().unwrap_or(0);
let max_attempts= params[1].get_i32().unwrap_or(0);
let maxsize = params[2].get_i32().unwrap_or(0);
let maxduration = params[3].get_f64().unwrap_or(0.0);
if let Some(ref mut connection) = obj.connection {
Box::new(methods::receive(connection, size, timeout, maxsize, maxduration))
Box::new(methods::receive(connection, timeout, max_attempts, maxsize))
} else {
Box::new(Vec::<u8>::new()) // Если соединения нет, возвращаем пустой массив
}

Binary file not shown.

Binary file not shown.

View File

@ -89,21 +89,29 @@
// Читает данные из указанного соединения
//
// Примечание:
// При установке параметров Таймаут и Размер в 0, чтение производится до окончания сообщения
// Метод пытается прочесть данные интервалами, длительность которых указана в параметре ДлительностьПопытки.^^
// За максимальное число попыток отвечает параметр ЧислоПопыток. При успешном получении новых данных число попыток сбрасывается.
// При работе с бесконечным потоком входящих данных обязательно указание параметра МаксимальныйРазмер, так как^^
// бесконечный сброс попыток при получении данных может привести к зависанию
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// Таймаут - Число - Время чтения данных (сек). 0 > до конца сообщения - timeout
// Размер - Число - Максимальный размер данных. 0 > без ограничений - size
// ДлительностьПопытки - Число - Интервал между попытками получения данных - timeout
// ЧислоПопыток - Число - Максимальное число попыток получения данных - attempts
// МаксимальныйРазмер - Число - Максимальный размер данных. 0 > без ограничений - size
//
// Возвращаемое значение:
// ДвоичныеДанные - Полученные данные
Функция ПолучитьДанные(Знач Соединение, Знач Таймаут = 0, Знач Размер = 0) Экспорт
Функция ПолучитьДанные(Знач Соединение
, Знач ДлительностьПопытки = 200
, Знач ЧислоПопыток = 5
, Знач МаксимальныйРазмер = 0) Экспорт
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Размер);
OPI_ПреобразованиеТипов.ПолучитьЧисло(ДлительностьПопытки);
OPI_ПреобразованиеТипов.ПолучитьЧисло(ЧислоПопыток);
OPI_ПреобразованиеТипов.ПолучитьЧисло(МаксимальныйРазмер);
Возврат Соединение.Read(1024, 150, Размер, Таймаут);
Возврат Соединение.Read(ДлительностьПопытки, ЧислоПопыток, МаксимальныйРазмер);
КонецФункции
@ -111,13 +119,17 @@
// Создает соединение и читает данные до конца или по ограничениям
//
// Примечание:
// При установке параметров Таймаут и Размер в 0, чтение производится до окончания сообщения
// Метод пытается прочесть данные интервалами, длительность которых указана в параметре ДлительностьПопытки.^^
// За максимальное число попыток отвечает параметр ЧислоПопыток. При успешном получении новых данных число попыток сбрасывается.
// При работе с бесконечным потоком входящих данных обязательно указание параметра МаксимальныйРазмер, так как^^
// бесконечный сброс попыток при получении данных может привести к зависанию
//
// Параметры:
// Адрес - Строка - Адрес и порт для подключения - address
// SSL - Булево - Признак использования защищенного соединения - ssl
// Таймаут - Число - Время чтения данных (сек). 0 > до конца сообщения - timeout
// Размер - Число - Максимальный размер данных. 0 > без ограничений - size
// ДлительностьПопытки - Число - Интервал между попытками получения данных - timeout
// ЧислоПопыток - Число - Максимальное число попыток получения данных - attempts
// МаксимальныйРазмер - Число - Максимальный размер данных. 0 > без ограничений - size
// Строкой - Булево - Истина > возвращает строку, Ложь > двоичные данные - string
// Кодировка - Строка - Кодировка получаемых данных - enc
//
@ -125,15 +137,14 @@
// Строка, ДвоичныеДанные - Полученные данные
Функция ПодключитьсяИПолучитьДанные(Знач Адрес
, Знач SSL = Ложь
, Знач Таймаут = 0
, Знач Размер = 0
, Знач ДлительностьПопытки = 0
, Знач ЧислоПопыток = 5
, Знач МаксимальныйРазмер = 0
, Знач Строкой = Истина
, Знач Кодировка = "UTF-8") Экспорт
OPI_ПреобразованиеТипов.ПолучитьБулево(Строкой);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Кодировка);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Размер);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
Соединение = ОткрытьСоединение(Адрес, SSL);
@ -141,7 +152,7 @@
ВызватьИсключение "Не удалось создать Соединение";
КонецЕсли;
Сообщение = ПолучитьДанные(Соединение, Таймаут, Размер);
Сообщение = ПолучитьДанные(Соединение, ДлительностьПопытки, ЧислоПопыток, МаксимальныйРазмер);
Если Строкой Тогда
Сообщение = ПолучитьСтрокуИзДвоичныхДанных(Сообщение);

View File

@ -89,21 +89,29 @@
// Читает данные из указанного соединения
//
// Примечание:
// При установке параметров Таймаут и Размер в 0, чтение производится до окончания сообщения
// Метод пытается прочесть данные интервалами, длительность которых указана в параметре ДлительностьПопытки.^^
// За максимальное число попыток отвечает параметр ЧислоПопыток. При успешном получении новых данных число попыток сбрасывается.
// При работе с бесконечным потоком входящих данных обязательно указание параметра МаксимальныйРазмер, так как^^
// бесконечный сброс попыток при получении данных может привести к зависанию
//
// Параметры:
// Соединение - Произвольный - Соединение, см. ОткрытьСоединение - tcp
// Таймаут - Число - Время чтения данных (сек). 0 > до конца сообщения - timeout
// Размер - Число - Максимальный размер данных. 0 > без ограничений - size
// ДлительностьПопытки - Число - Интервал между попытками получения данных - timeout
// ЧислоПопыток - Число - Максимальное число попыток получения данных - attempts
// МаксимальныйРазмер - Число - Максимальный размер данных. 0 > без ограничений - size
//
// Возвращаемое значение:
// ДвоичныеДанные - Полученные данные
Функция ПолучитьДанные(Знач Соединение, Знач Таймаут = 0, Знач Размер = 0) Экспорт
Функция ПолучитьДанные(Знач Соединение
, Знач ДлительностьПопытки = 200
, Знач ЧислоПопыток = 5
, Знач МаксимальныйРазмер = 0) Экспорт
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Размер);
OPI_ПреобразованиеТипов.ПолучитьЧисло(ДлительностьПопытки);
OPI_ПреобразованиеТипов.ПолучитьЧисло(ЧислоПопыток);
OPI_ПреобразованиеТипов.ПолучитьЧисло(МаксимальныйРазмер);
Возврат Соединение.Read(1024, 150, Размер, Таймаут);
Возврат Соединение.Read(ДлительностьПопытки, ЧислоПопыток, МаксимальныйРазмер);
КонецФункции
@ -111,13 +119,17 @@
// Создает соединение и читает данные до конца или по ограничениям
//
// Примечание:
// При установке параметров Таймаут и Размер в 0, чтение производится до окончания сообщения
// Метод пытается прочесть данные интервалами, длительность которых указана в параметре ДлительностьПопытки.^^
// За максимальное число попыток отвечает параметр ЧислоПопыток. При успешном получении новых данных число попыток сбрасывается.
// При работе с бесконечным потоком входящих данных обязательно указание параметра МаксимальныйРазмер, так как^^
// бесконечный сброс попыток при получении данных может привести к зависанию
//
// Параметры:
// Адрес - Строка - Адрес и порт для подключения - address
// SSL - Булево - Признак использования защищенного соединения - ssl
// Таймаут - Число - Время чтения данных (сек). 0 > до конца сообщения - timeout
// Размер - Число - Максимальный размер данных. 0 > без ограничений - size
// ДлительностьПопытки - Число - Интервал между попытками получения данных - timeout
// ЧислоПопыток - Число - Максимальное число попыток получения данных - attempts
// МаксимальныйРазмер - Число - Максимальный размер данных. 0 > без ограничений - size
// Строкой - Булево - Истина > возвращает строку, Ложь > двоичные данные - string
// Кодировка - Строка - Кодировка получаемых данных - enc
//
@ -125,15 +137,14 @@
// Строка, ДвоичныеДанные - Полученные данные
Функция ПодключитьсяИПолучитьДанные(Знач Адрес
, Знач SSL = Ложь
, Знач Таймаут = 0
, Знач Размер = 0
, Знач ДлительностьПопытки = 0
, Знач ЧислоПопыток = 5
, Знач МаксимальныйРазмер = 0
, Знач Строкой = Истина
, Знач Кодировка = "UTF-8") Экспорт
OPI_ПреобразованиеТипов.ПолучитьБулево(Строкой);
OPI_ПреобразованиеТипов.ПолучитьСтроку(Кодировка);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Размер);
OPI_ПреобразованиеТипов.ПолучитьЧисло(Таймаут);
Соединение = ОткрытьСоединение(Адрес, SSL);
@ -141,7 +152,7 @@
ВызватьИсключение "Не удалось создать Соединение";
КонецЕсли;
Сообщение = ПолучитьДанные(Соединение, Таймаут, Размер);
Сообщение = ПолучитьДанные(Соединение, ДлительностьПопытки, ЧислоПопыток, МаксимальныйРазмер);
Если Строкой Тогда
Сообщение = ПолучитьСтрокуИзДвоичныхДанных(Сообщение);