gifts2017

1CHServer - внешняя компонента, позволяющая реализовать выполнение кода в другом сеансе 1С Предприятия по запросу клиента.

Опубликовал Александр Шкураев (salexdv) в раздел Программирование - Внешние компоненты

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

Понадобилось мне реализовать отображении информации об остатках из одной базы в другой в реальном времени.

Держать у каждого пользователя в сеансе дополнительное COM-соединение не очень хотелось. Так и родилось данное решение.

 

Принцип работы довольно прост:

  1. На компьютере (назовем его сервером) запускается обработка, где создается объект "AddIn.1CHServer" Этот сервер будет прослушивать определенный порт и ожидать входящий запрос от клиента.
  2. Клиент отправляет запрос серверу с помощью объекта HTTPСоединение
  3. AddIn.1CHServer получив запрос генерирует внешнее события для сеанса 1С Предприятия в котом данный объект создан
  4. На сервере выполняется запрошенный клиентом код и результат возвращается клиенту при помощи метода ВернутьРезультат(...)

Результат, возвращаемый клиенту может быть только тексовым т.к. запрос отправляется при помощи метода Получить() объекта HHTPСоединение

Теперь вместо того, чтобы держать 10-15 постоянных COM-соединений клиент лишь отправляет текст кода для выполнения в сеансе, где создан AddIn.1CHServer и получает ответ.

Работает, конечно, медленнее, чем при могло бы быть через "V8x.ComConnector", но есть и свои преимущества. Например, если надо срочно обновить базу данных, то не надо убивать все COM-сеансы, а достаточно просто остановить на время 1CHServer и обновить БД.

Не рекомендуется выполнять "тяжелый" код на сервере, т.к. это замедлит получение ответа другими клиентами.

ОПИСАНИЕ КОМНОНЕНТЫ

Методы:

  • Запустить(<Порт>) - запуск прослушивания указанного порта;
  • Остановить() - остановка сервера;
  • ВернутьРезультат(<ТекстовыйРезультат>) - возврат результата клиенту (метод обязательно должен вызываться, иначе сервер перестанет принимать входящие запросы от клиентов);

Свойства:

  • Порт - порт на котором работает сервер (только чтение);

В случае ошибки (при работе компоненты или при выполнении кода на сервере) возвращается результат вида: Error: <ОписаниеОшибки>

 

В коде, выполняемом на сервере, не должно быть комментариев

Для работы компоненты потребуется установленный Microsoft .NET Framework 2.0, взять его можно отсюда.

Регистрация компоненты в Windows - запустить reg.bat
Удаление информации о компоненте - запустить unreg.bat

Прилагаются примеры обработок для сервера и для клиента (8.2)

Критика и предложения приветствуются.

 

http://shkuraev.ru


Скачать файлы

Наименование Файл Версия Размер
1CHServer.zip 115
.zip 32,35Kb
20.12.10
115
.zip 32,35Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Сергей Лунев (luns) 20.12.10 11:52
Плюс авансом.
Штука полезная если работает.
2. Герман (German) 20.12.10 12:57
http://main.1c-ei.ru/Articles/fone-run

100 лет в обед, и без всяких ВК, просто на регламентных заданиях
3. Alxd (salexdv) 20.12.10 13:13
German пишет:
http://main.1c-ei.ru/Articles/fone-run
100 лет в обед, и без всяких ВК, просто на регламентных заданиях


Ну и как с помощью всего этого получить, например, остатки из базы, которая находится другом здании, городе, стране?
4. Герман (German) 20.12.10 13:21
наверно с помощью это никак только Web сервисы

Результат, возвращаемый клиенту может быть только тексовым т.к. запрос отправляется при помощи метода Получить() объекта HHTPСоединение

Да и вашем случае реализация не очень
5. Alxd (salexdv) 20.12.10 13:25
Очень или нет, но она стабильно работает ))
6. Игорь Исхаков (Ish_2) 20.12.10 14:15
В 8-ке ВК - это зло по определению.
Публикация таких ВК , может представлять интерес как демонстрация некоторых возможностей,
как некий прикол.
Претендовать же на некое технологичное решение, которое стоит рассматривать всерьез - Боже упаси !
7. Alxd (salexdv) 20.12.10 14:47
Ну давайте тогда поубиваем всякие AddIn.Scaner45, AddIn.FprnM45 и пр., да и будет радоваться на голую 8-ку без ТО и прочих нужных вещей
Без моей компоненты очень даже можно обойтись - это просто пример решения одной из задач.
Но в целом с высказыванием совершенно не согласен.
ВК и в 7-ке и в 8-ке - вещь!
8. Александр Цегельников (markers) 21.12.10 11:15
Alxd,
Лично я считаю что от ВК (вообще) в 8-ке нет толку потому-что очень многое хочется увести на выполнение в фоне, и в нём хочется реализовать интересные штуки, но ВК там нету! Тока ком! По этому я не вижу смысла писать ВК, если на 8-ке не всегда применимо.
9. Ийон Тихий (cool.vlad4) 21.12.10 17:51
:D от ВК нет толку, ну, ну, ну ...я и смотрю как народ йоксели, мираклы или душеловские наработки скачивает...ВК это единственный способ протянуть мост из 1С в ООП, со всеми вытекающими последствиями - как всякий мост он хуже протоптанных троп, но и без него никуда...Даже в 1С используют ВК (namedcl или как он там, библиотечка склонений) Так, что не надо про ВК.
ЗЫ я уж не говорю про работу всякой периферии (сканеры и т.п.)
ЗЫ порой смотришь, что сама 1С посылает на SQL и диву даешься, вся 1С это сплошной ВК...шучу, конечно...
PS А последний пост, это, конечно, тоже прикол, "тока com" и никаких ВК, только велосипед и никаких колес...
10. Василий Демидов (Душелов) 21.12.10 21:21
Хорошо ) Идею можно развить и довести до ума ;)

А получение данных с удаленных баз я сделал и без веб-сервисов и ВК - 8.2, использую комобъект тонкого клиента, с соединением с вебсервером и сериализацией полученного результата. Плюс в том, что передаешь произвольный текст запроса. Главное правильно передать параметры )
11. Alxd (salexdv) 21.12.10 21:38
Душелов пишет:
А получение данных с удаленных баз я сделал и без веб-сервисов и ВК - 8.2, использую комобъект тонкого клиента, с соединением с вебсервером и сериализацией полученного результата. Плюс в том, что передаешь произвольный текст запроса. Главное правильно передать параметры )


Тоже ловко :-)
12. Олег Молочников (milkers) 26.12.10 10:00
Остаются большие вопросы с безопасностью. Как гарантировать, что компонента не содержит закладок? Как гарантировать что произвольный код на сервере не выполнит кто-нибудь другой?
Можно отрыть порт на доступ только с определенного внешнего ip, но это элементарно обходится.
13. Alxd (salexdv) 26.12.10 12:05
(12) Можно воспользоваться TCPViewer и понаблюдать за соединениями. Если останутся сомнения, то никто не мешает реализовать какую-нибудь другую схему без использования компоненты
14. Николай Павлучинский (mykolap) 27.07.11 12:32
Веб сервисы для таких целей как по мне гораздо лучше.
На практике для выполнения похожих задач пользуюсь именно ими.
15. Alxd (salexdv) 27.07.11 12:47
(14) Несомненно, веб-сервисы ловчее будут.
Только не всегда быстрее. При моей постановки задачи 1CHServer обрабатывает до 100 мелких запросов в секунду (реальная нагрузка, пока от 1 до 20 запросов в секунду).
Проповал Apache, не так шустер он.
16. kabz (Kabz) 22.09.11 00:22
Все хорошо и лог есть но есть проблема
даю такую команду http://127.0.0.1:1245/taxi/1.x/requestcar
получаю
22.09.2011 0:17:32 - Возвращен ответ: возратtax
22.09.2011 0:17:32 - Входящее соединение (127.0.0.1:51162)
22.09.2011 0:17:32 - Текст запроса:
favicon.ico
22.09.2011 0:17:32 - Возвращен ответ: возратfavicon.ico
17. kabz (Kabz) 22.09.11 00:24
а если даю http://127.0.0.1:1245/taxi1.xrequestcar
22.09.2011 0:23:05 - Входящее соединение (127.0.0.1:51217)
22.09.2011 0:23:05 - Текст запроса:
taxi1.xrequestcar
22.09.2011 0:23:05 - Возвращен ответ: возратtaxi1.xrequestcar

то есть почему то коряво обрабатываются / обрезает и добавляет какую то чуш ... ,
18. Ийон Тихий (cool.vlad4) 22.09.11 00:58
(17) Почему ты решил, что коряво обрабатывается? Тебе не совсем это нужно, прочитай 10 пост и вспомни что я говорил про com
19. Alxd (salexdv) 22.09.11 09:19
(16) Что-то я не пойму, что вы вообще пытаетесь сделать?
20. Ийон Тихий (cool.vlad4) 22.09.11 10:25
(19) Да ему нужно отвечать на веб запросы ,а данные по всей видимости брать из 1С - http://forum.infostart.ru/forum26/topic42376/message453838/#message453838 ...я и предложил делать веб сервис и через com например брать данные.
21. kabz (Kabz) 22.09.11 12:36
Все просто слушаю порт 1245 на сервере даю команду в лисе http://127.0.0.1:1245/taxi/1.x/requestcar
если в команде есть / то компонента дает 2 денные часть строки + favicon.ico - откуда она это берет не пойму
если команда например такая http://127.0.0.1:1245/taxi_1.x_requestcar то данные поступаю правельные taxi_1.x_requestcar
22. Alxd (salexdv) 22.09.11 13:05
(21) Просто выделение текста запроса в компоненте идет по символу "/", поэтому и такой результат
Именно поэтому в публикации красным написано
В коде, выполняемом на сервере, не должно быть комментариев
23. kabz (Kabz) 22.09.11 13:34
обидно хотел для другово немного использовать.
24. Alxd (salexdv) 22.09.11 13:42
(23) Предлагаю для удобства подправить код самого сервера и ввести некие аббревиатуры для команд.
Что-то вроде http://127.0.0.1:1245/АПокажиКаМнеДругОстатки

На сервере
Если Команда = "АПокажиКаМнеДругОстатки" Тогда
   ........
КонецЕсли


И все будет замечательно ;)
25. kabz (Kabz) 22.09.11 16:06
Только команды не я присылаю .. , а так бы использовал.. там в команде еще xml внутри ...
26. Alxd (salexdv) 22.09.11 16:13
(25) Могу подправить компоненту, только требуется более подробное описание входящих запросов. Пишите на почту
27. Аркадий Кучер (Abadonna) 23.09.11 10:50
(6)
В 8-ке ВК - это зло по определению.

ВК зло, потому что я ни фига их писать не умею, 8х- отстой, потому что мне влом да и слабо в ней разобраться, 77- гуд.
Так? ;)
Это я твою мысль слегка развил в помощь апологетам семерки
28. Игорь Исхаков (Ish_2) 26.09.11 01:23
(27) Через год прострелило. Ответил-таки.
Ну погоди ! Я тебе через год так отвечу - все ахнут.
29. Осипов Сергей (fixin) 28.05.12 20:16
30. Александр Шкураев (salexdv) 28.05.12 22:40
(29) Простота накладывает свои жесткие ограничения
    Требуется изменение конфигурации;
    Сильно грузится процессор;
    Нет возможности запускать "сервер" на совсем удаленном компьютере;
31. Осипов Сергей (fixin) 29.05.12 10:49
(30) ваш метод не требует изменения конфигурации? ;-)
для ускорения и вам придется загружать центральный сервер, другого не дано. Терминальное подключение тоже загружает центральный сервер.
Нет возможности запускать "сервер" на совсем удаленном компьютере - ну почему же, можно формировать файл запроса и получать файл ответа, ноу проблемс....
32. Alexandr Климчук (undo) 29.12.13 19:08
Обработка классная как вариант можно в файл писать не историю обращений а текущий список обращений.
т.е. каждому входящему обращению к серверу присваивается уникальный номер, дальше данный номер передается во внешнем событии. Само событие может содержать произвольный текст в заголовке которого и есть данный уникальный номер, текст к примеру может быть упакован в что-то типа контейнера из начального и конечного символа.
после обработки запроса, его ответ пакуется в контейнер с тем же уникальным номером и отправляется обратно. Это позволит принимать сразу несколько входящих задач разделённые между собой. или это бред.
Тогда в случае выполнения тяжелого запроса обработка сможет продолжить принимать данные и ставить их в очередь.
33. Alexandr Климчук (undo) 29.12.13 19:09
а если текст паковать в контейнер из условных символов, то это позволит передавать на сервер и принимать с него любой набор символов.
34. Александр Шкураев (salexdv) 29.12.13 19:49
(32) Так никто не мешает это реализовать. На клиенте просто, как вам надо, формируете пакет и через HTTPСоединение текстом передаете серверу. Он его выполняет. Все, что вы опишете на встроенном языке без ошибок, на сервере выполнится.
Ну либо можно переделать обработку для сервера.
35. Alexandr Климчук (undo) 29.12.13 20:16
Спасибо, это писал к ограничению на использование комментариев.
Если компонента их обрабатывает и неправильно на них реагирует или это сам протокол HTTPСоединение неправильно их обрабатывает.? Если протокол то да тут управляющими символами пожалуй не получится исправить ситуацию, а вот если сама компонента тогда дело поправимо. и конечно не исключаю что я сильно заблуждаюсь.
36. Александр Шкураев (salexdv) 29.12.13 20:23
(35) Во всем виновато HTTPСоединение
37. Alexandr Климчук (undo) 29.12.13 20:29
Прискорбно что таким продуктивным вещам мешают такие древние :) технологии, но ничто не мешает использовать её по принцыпу ключевых слов.
38. Александр Шкураев (salexdv) 29.12.13 20:36
(37) Может я плохо искал и слэш можно как-то экранировать
39. Alexandr Климчук (undo) 29.12.13 22:40
не знаю поможет ли это другим, но мою проблему решило.

Функция Кодировать(Стр, Кодировка)
ЦДО= Новый COMОбъект("CDO.Message");
БодиПарт=ЦДО.BodyPart;
Поля=БодиПарт.Fields;
Поле=Поля.Item("urn:schemas:mailheader:content-type");
Поле.Value="text/plain; charset=""windows-1251""";
Поля.Update();
Стрим = БодиПарт.GetDecodedContentStream();
Стрим.charset = "windows-1251";
Стрим.WriteText(Стр);
Стрим.Flush();
БодиПарт.ContentTransferEncoding = Кодировка;
Стрим=БодиПарт.GetEncodedContentStream();
Возврат Стрим.ReadText();
КонецФункции // Кодировать64(Стр)

Процедура ОсновныеДействияФормыВыполнитьНаСервере(Кнопка)

Если НЕ ЗначениеЗаполнено(АдресСервера) Тогда
Предупреждение("Не указан адрес сервера!");
Возврат
КонецЕсли;

Если НЕ ЗначениеЗаполнено(Порт) Тогда
Предупреждение("Не указан порт!");
Возврат
КонецЕсли;

Запрос = ЭлементыФормы.ТекстЗапроса.ПолучитьТекст();
Кодировка = "base64";
Запрос=Кодировать(Запрос,Кодировка);

Если ЗначениеЗаполнено(Запрос) Тогда
ОтправитьЗапросНаСервер(Запрос);
Иначе
Предупреждение("Не указан код, который должен выполняться на сервере.");
КонецЕсли;

КонецПроцедуры

В обработке сервера
Функция Декодировать(Стр, Кодировка)
ЦДО= Новый COMОбъект("CDO.Message");
БодиПарт=ЦДО.BodyPart;
БодиПарт.ContentTransferEncoding = Кодировка;
Стрим=БодиПарт.GetEncodedContentStream();
Поля=БодиПарт.Fields;
Поле=Поля.Item("urn:schemas:mailheader:content-type");
Поле.Value="text/plain; charset=""windows-1251""";
Поля.Update();
Стрим.WriteText(Стр);
Стрим.Flush();
Стрим = БодиПарт.GetDecodedContentStream();
Стрим.charset = "windows-1251";
Возврат Стрим.ReadText();
КонецФункции // Декодировать64(Стр)

Функция ВыполнитьЗапросКлиента(Запрос)

Результат = "";
СтруктураРезультата = Новый Структура("Ошибка, ОписаниеОшибки, Результат", Ложь, "", "");

Кодировка = "base64";
Запрос = Декодировать(Запрос,Кодировка);

Попытка
Выполнить(Запрос);
Исключение
Результат = "Error: " + ОписаниеОшибки();
КонецПопытки;

Возврат Строка(Результат);

КонецФункции
40. Alexandr Климчук (undo) 29.12.13 22:43
т.е. суть в следующем, предварительно перед передачей запроса, я его кодирую в Base64, а при получении перед передачей на выполнение обратно его декодирую. Образец кодирования и декодирования взял у smaharbA с "mista" за что ему большое спасибо.
Не проверял насколько это сказывается на быстродействии данной обработки но факт имеет место.
41. Александр Шкураев (salexdv) 29.12.13 23:02
(40) Вот я и говорю, что проблему можно решить простой модификацией обработки клиента и "сервера". Компонента - лишь обеспечивает связь с "сервером", а дальше все в ваших руках
42. Alexandr Климчук (undo) 29.12.13 23:12
Верное замечание, дальше уже есть мысль что нужно полученный ответ запроса, любого виды через функцию ЗначениеВФайл сохранить во временный файл перекодировать его в base64 и отправить клиенту на раскодирование. Таким образом можно и таблицы значений передавать и любые другие объекты предпологаю.
Конечно в этом случае предпологается идентичность идентификаторов данных или использовать в запросе представления объектов и передавать в таблице значений только текстовые представления данных.
Вообщем ОГРОМНЫЙ зачет.
43. Alexandr Климчук (undo) 29.12.13 23:14
Нужно будет попробовать реализовать данный момент на 7.7
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа