1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-07-07 01:09:03 +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( pub fn receive(
connection: &mut Connection, connection: &mut Connection,
buffer_size: i32,
timeout_ms: i32, timeout_ms: i32,
max_attempts: i32,
max_data_size: i32, max_data_size: i32,
max_duration_s: f64,
) -> Vec<u8> { ) -> Vec<u8> {
const BUFFER_SIZE: usize = 4096; // Фиксированный размер буфера
let mut result = Vec::new(); let mut result = Vec::new();
let mut buffer = vec![0u8; buffer_size as usize]; let mut buffer = vec![0u8; BUFFER_SIZE];
let start_time = Instant::now(); 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 { match connection {
Connection::Tcp(stream) => { 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) => { 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 { loop {
// Проверяем ограничения, если они заданы // Завершаем цикл, если превышен лимит данных
if (max_data_size > 0 && result.len() >= max_data_size as usize) || 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)) {
break; break;
} }
match connection.read(&mut buffer) { match connection.read(&mut buffer) {
Ok(0) => break, // EOF - конец данных Ok(0) => break, // Конец данных (EOF)
Ok(size) => result.extend_from_slice(&buffer[..size]), Ok(size) => {
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, // Таймаут result.extend_from_slice(&buffer[..size]);
Err(_) => break, // Любая другая ошибка 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 { match num {
0 => 0, 0 => 0,
1 => 0, 1 => 0,
2 => 4, 2 => 3,
3 => 2, 3 => 2,
_ => 0, _ => 0,
} }
@ -41,13 +41,13 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
}, },
2 => { 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 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 { 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 { } else {
Box::new(Vec::<u8>::new()) // Если соединения нет, возвращаем пустой массив Box::new(Vec::<u8>::new()) // Если соединения нет, возвращаем пустой массив
} }

Binary file not shown.

Binary file not shown.

View File

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

View File

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