Внешняя Native API компонента для 1C 8.3, которая реализует синхронный TCP сервер. Основное назначение компоненты - работа в режиме TCP сервера, но она также может использоваться как TCP клиент. Компонента реализована на C++ с использованием библиотек Boost. Работа с сокетами реализована с использованием библиотеки Boost.Asio.
Методы сервера реализованы в синхронном, а не в асинхронном варианте, чтобы упростить отладку и доработку компоненты. Библиотека Boost.Asio выбрана поскольку она сочетает в себе максимальную гибкость работы с сокетами, производительность и надежность. Так же в Boost.Asio заложены возможности использования не только TCP сокетов, но также UDP-сокетов и COM-портов, что позволяет с минимальными изменениями в структуре кода адаптировать компоненту под специфику своей задачи.
Сервер TCP может работать с произвольным количество соединений как на одном, так и на разных портах (что не позволяет делать стандартная MSWINSCK.OCX от Microsoft). Компонента так же реализует много фич, которых нет в MSWINSCK.OCX. Например, в зависимости от сценария для каждого порта можно настраивать различные параметры:
Компонента протестирована в ходе множества реальных внедрений и стабильно работает с большим количеством подключений и интенсивным трафиком сообщений. Основным сценарием использования компоненты в продакшене была интеграция медицинского оборудования и лабораторной информационной системой на платформе 1С.
Задает параметры работы сервера, но не запускает его. Если параметры сервера указаны не корректно, то выдается ошибка.
Параметры:
Запускает сервер TCP. На каждом порте сервера, где isLinkToRemoteServer = ЛОЖЬ, открываются сокеты, которые ждут подключений клиентов. Если на каком-то порте сокет уже открыт другим сервером, тогда сервер не стартует, а возвращается строка JSON с описанием ошибки.
Записывает в переменную ВходящиеСообщенияJson строку JSON с данными о принятых сообщениях, которые не были еще обработаны. Функция возвращается ИСТИНА, если есть входящие сообщения или по истечение времени Таймаут_мс. Функция предназначена для использования в качестве условия в цикле, например:
ВходящиеСообщенияJson = "";
Пока КомпонентаСервер.GetMessagesFromClientsWhenArrive(ВходящиеСообщенияJson, ЧастотаПроверки_мс, Таймаут_мс) Цикл
...
КонецЦикла;
Параметры:
Записывает в переменную ВходящиеСообщенияJson строку JSON с данными о принятых сообщениях, которые не были еще обработаны. Функция возвращается ИСТИНА, если есть входящие сообщения. Функция предназначена для периодического вызова, например со стороны клиента 1С через обработчик ожидания. Нужно отметить, что функция GetMessagesFromClients выполняется значительно быстрее, чем функция GetMessagesFromClientsWhenArrive, но ее использование как условия в цикле "Пока" крайне нежелательно, так как это приведет к возрастанию загрузки процессора.
Параметры:
Передает компоненте, GUID принятых сообщений, чтобы они были помечены как обработанные. Обработанные сообщения не смогут быть вновь получены методами GetMessagesFromClientsWhenArrive и GetMessagesFromClients. В дальнейшем обработанные сообщения будут асинхронно удалены из памяти компоненты заданием, выполняемым с периодичностью memoryCleaningFrequency.
Параметры:
Передает компоненте сообщение для последующей отправки клиенту, подключенному к сокету сервера. Исходящие сообщения в дальнейшем будут обработаны и отправлены асинхронно в отдельном потоке.
Параметры:
Передает компоненте сообщение для последующей отправки в сокет, открытый удаленным сервером. Исходящие сообщения в дальнейшем будут обработаны и отправлены асинхронно в отдельном потоке.
Параметры:
Возращает информацию о текущем состоянии сокетов на портах.
Возвращаемое значение (строка JSON):
Получает записи логов сервера. Полученные записи можно сохранить в регистре сведений для удобства просмотра.
Параметры:
Возвращаемое значение (строка JSON):
Останавливает сервер и закрывает все сокеты.
Отправляет сигнал останова работающему экземпляру сервера, если такой существует. Сигнал останова задается в параметре serverTerminationSignal. После получения сиглала останова сервер закрывает сокеты на всех портах и завершает все активные потоки. Если экземпляр сервера был запущен как фоновое задание, то фоновое задание завершается.
В файле _SynchClientServer.cfe, прикрепленном к релизу, находится демонстрационная конфигурация 1C 8.3, содержащая примеры методов работы с компонентой.
Процедура ЗапуститьКомпонентуВТекущемПотоке() Экспорт
ПараметрыЗапущеннойКомпоненты = ЗапуститьКомпоненту();
Если ПараметрыЗапущеннойКомпоненты <> Неопределено Тогда
ЗапуститьЦиклОбработкиСообщенийСервера(
ПараметрыЗапущеннойКомпоненты.ВнешняяКомпонента,
ПараметрыЗапущеннойКомпоненты.ПараметрыРаботыКомпоненты);
КонецЕсли;
КонецПроцедуры
Процедура ЗапуститьЦиклОбработкиСообщенийСервера(ВнешняяКомпонента, ПараметрыРаботыКомпоненты)
ПараметрыОбновленияСлужебнойИнформации = ПараметрыОбновленияСлужебнойИнформацииОРаботеКомпоненты();
ЧастотаПроверки_мс = 1000;
Таймаут_мс = 10000;
ВходящиеСообщенияJson = "";
Пока ВнешняяКомпонента.GetMessagesFromClientsWhenArrive(ВходящиеСообщенияJson, ЧастотаПроверки_мс, Таймаут_мс) Цикл
Если ЗначениеЗаполнено(ВходящиеСообщенияJson) Тогда
ВходящиеСообщенияСтруктура = СтруктураИзСтрокиJson(
ВходящиеСообщенияJson, Истина);
ВходящиеСообщенияJson = "";
Если ЗначениеЗаполнено(ВходящиеСообщенияСтруктура) Тогда
ПодтвердитьПолучениеСообщений(
ВнешняяКомпонента, ВходящиеСообщенияСтруктура);
ОбработатьВходящиеСообщения(
ВнешняяКомпонента,
ВходящиеСообщенияСтруктура,
ПараметрыРаботыКомпоненты);
КонецЕсли;
КонецЕсли;
ОбновитьСлужебнуюИнформациюОРаботеКомпонентыВБазе(
ВнешняяКомпонента, ПараметрыОбновленияСлужебнойИнформации);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЗапуститьКомпонентуНаКлиенте(Команда)
ПараметрыЗапущеннойКомпоненты = бит_КомпонентаSynchClientServerКлиентСервер.ЗапуститьКомпоненту();
Если ПараметрыЗапущеннойКомпоненты <> Неопределено Тогда
ПодключитьОбработчикОжидания("ОбработатьНовыеСообщения", 1);
Иначе
ОтключитьОбработчикОжидания("ОбработатьНовыеСообщения");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьНовыеСообщения() Экспорт
бит_КомпонентаSynchClientServerКлиентСервер.ОбработатьНовыеСообщения(
ПараметрыЗапущеннойКомпоненты.ВнешняяКомпонента,
ПараметрыЗапущеннойКомпоненты.ПараметрыРаботыКомпоненты);
КонецПроцедуры
Процедура ОбработатьНовыеСообщения(ВнешняяКомпонента, ПараметрыРаботыКомпоненты) Экспорт
ВходящиеСообщенияJson = "";
ВнешняяКомпонента.GetMessagesFromClients(ВходящиеСообщенияJson);
Если ЗначениеЗаполнено(ВходящиеСообщенияJson) Тогда
ВходящиеСообщенияСтруктура = СтруктураИзСтрокиJson(
ВходящиеСообщенияJson, Истина);
Если ЗначениеЗаполнено(ВходящиеСообщенияСтруктура) Тогда
ПодтвердитьПолучениеСообщений(
ВнешняяКомпонента, ВходящиеСообщенияСтруктура);
ОбработатьВходящиеСообщения(
ВнешняяКомпонента,
ВходящиеСообщенияСтруктура,
ПараметрыРаботыКомпоненты);
КонецЕсли;
КонецЕсли;
ВходящиеСообщенияJson = "";
КонецПроцедуры
b2.exe -j4 toolset=msvc-14.2 address-model=64 architecture=x86 link=static threading=multi runtime-link=static --build-type=complete --build-dir=build\x64 stage
b2.exe -j4 toolset=msvc-14.2 address-model=32 architecture=x86 link=static threading=multi runtime-link=static --build-type=complete --build-dir=build\x32 stage
7. Скачать библиотеку [rapidjson](https://github.com/Tencent/rapidjson/) для работы с JSON. Указать пути к каталогам
библиотеки в свойствах проекта.
## Сборка компоненты под Linux
Сборку необходимо производить только на Ubuntu 18 или Debian 9.
1. Скачать исходники репозитория данного проекта.
2. Скачать набор библиотек Boost. Проверенная версия 1.72.0.
```sh
sudo apt-get update
sudo apt install build-essential cmake
cd
wget -O boost_1_72_0.tar.gz https://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.gz/download --no-check-certificate
tar xzvf boost_1_72_0.tar.gz
cd boost_1_72_0/
sudo apt-get update
sudo apt-get install build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev libboost-all-dev
./bootstrap.sh
./b2
sudo ./b2 install
git clone https://github.com/Tencent/rapidjson.git
cd rapidjson/
cmake .
make install
cd linux
mkdir tmp_build && cd tmp_build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
Фичи ждут своих контрибьютеров.
Если Вы нашли какую-нибудь ошибку или хотите предложить доработку проекта, то порядок следующий:
git checkout -b issue-9999