Пример реализации обмена с оборудованием через winsocket на управляемых формах по протоколу TCP

0. Евгений Абдуразаков (asdfgcom) 106 09.01.17 13:07 Сейчас в теме
Объединяя опыт коллег с данного ресурса, хочу поделиться своим решением с подключением контроллера контроля доступа к 1С УНФ. Здесь описан метод без использования ActiveX, который не работает на УФ.

Перейти к публикации

Комментарии
1. Антон Стеклов (asved.ru) 33 11.01.17 10:24 Сейчас в теме
Засунуть COMОбъект в параметры сеанса временное хранилище, да еще по произвольному адресу - это, конечно, сильный ход. И неожиданный.

Вы его еще на клиента передать попробуйте. Или в базу записать.
3. Евгений Абдуразаков (asdfgcom) 106 11.01.17 15:22 Сейчас в теме
(1) этот метод как раз рассматривался на инфостарте. Очень выручил. Глобально не получается держать COMобъект, т.к. после выполнения на сервере и повторном входе переменная переинициализируется. В реквизитах объекта держать нельзя. Они доступны клиенту, а COMобъекты не сереализуются. Как тогда? Остается хранилище. Как передать несереализуемый объект? Прячем его в, например, структуру...

(2) попробую.

Только что перепроверил, почему не работал "ДобавитьОбработчик". Заставил работать по событиям.
Где-то накосячил с передачей между клиентом и сервером, что вызывало appCrash 1с.exe
На самом деле все будет гораздо проще.

ДобавитьОбработчик ws.Connect, Connect; 
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest; 
ДобавитьОбработчик ws.DataArrival, DataArrival;
ДобавитьОбработчик ws.Error, WinSocketError;

И все взлетело. Избавился от ежесекундных обработчиков.
Статью перепишу на днях.
4. Антон Стеклов (asved.ru) 33 11.01.17 17:23 Сейчас в теме
(3) Как вы думаете, что из себя представляет COMОбъект, и что помещается во временное хранилище?
И что Вы достанете из хранилища в следующем вызове, когда следующий вызов будет исполняться на другом сервере кластера, или после перезапуска процесса? Или после разрыва сетевого соединения?

jONES1979; +1 Ответить
5. Евгений Абдуразаков (asdfgcom) 106 11.01.17 21:13 Сейчас в теме
(4) Надеюсь, я Вас правильно понял.
В Параметрах сеанса мы держим только строку с адресом временного хранилища в котором лежит наш COMобъект. Методика, описана на волшебном форуме (не уверен, что можно явно ссылаться на сторонние форумы, поэтому поиск) "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"
На счет другого сервера кластера - не знаю... Но и не надо, надеюсь. Ведь COMобъект в хранилище, адрес и уникальный идентификатор у нас имеется. Всегда поднимем объект.
После разрыва сетевого соединения получим ошибку, переподключимся и сунем обратно адрес на хранилище.
7. Антон Стеклов (asved.ru) 33 12.01.17 14:58 Сейчас в теме
(5)
Всегда поднимем объект.


Поднимите объект через 21 минуту неактивности.

Это работает исключительно потому, что сериализация и собственно запись во временное хранилище производится отложенно. Т.е. несериализуемая ссылка на COM-объект находится в кэше рабочего процесса. Как только сервер попытается ее сериализовать - тут-то она и уничтожается.

Другой сервер кластера или клиент при попытке получения значения инициирует его физическую сериализациию, т.к. обращается к сервису сеансовых данных. Т.е. обращение к объекту с другого сервера кластера уничтожит его и на первом сервере.
9. Евгений Абдуразаков (asdfgcom) 106 12.01.17 17:57 Сейчас в теме
(7)(8) Приветствую, Антон!
Да, все верно. Однако в моем случае не критично.
Winsocket используется только для связи с оборудованием. Во время обращения к нему соединение не потеряется. Факт. Если COMОбъект теряется из временного хранилища (при простое), то ошибка соединения - переподключение с переинициализацией COMобъекта. Я этого даже не замечал. Для интереса, поставлю точку в отладчике в процедуре переподключения, убедиться, что соединение теряется. Переинициализацию сделал как раз из-за предупреждения в вышепредложенной статье автора H A D G E H O G s:
"ComОбъект теряется на 20 -ой минуте его "неиспользования". Так сделали 1С. Столько живет объект во временном хранилище, если у него нет идентификатора - формы владельца. Лечение просто - раз в 500 секунд - считывать COMОбъект из Временного хранилища".
13. Евгений Абдуразаков (asdfgcom) 106 12.01.17 19:39 Сейчас в теме
(1) Антон, прошу прощения за невнимательность.
Вы имели в виду мою неточность в описании, точнее некорректное построение фразы:

"Заметим, что COMобъект мы спрятали в структуру... А если "спрятать" его в структуру, ошибок не будет"

Точнее было бы сказать. ...а если спрятать его в структуру, разместить во временное хранилище, тогда ссылку на временное хранилище мы можем передать в переменную, хранимую в параметрах сеанса для того, чтобы использовать ее и на клиенте, и в серверных вызовах без переинициализации самого объекта.. И т.д. (получилось много букв. Я бы читать не стал с этого места дальше.))))
2. mdl mdl (mdl@andi72.ru) 11.01.17 10:37 Сейчас в теме
ActiveX в УФ поддерживается, не официально. Делал через реализацию интерфейсов для ie:

GetInterfaceSafetyOptions, SetInterfaceSafetyOptions

ну естественно под win
6. Павел Одинцов (Darklight) 5 12.01.17 14:33 Сейчас в теме
Большое списбо за статью, познавательно!
Сам храню COM-объекты через модули повторного использования - тоже ретушируются (без упаковки в структуру; как возвращаемые значения), но есть свои неудобства такого подхода.
Но технология COM - это уже прошлый век.
Что же делать под Linux?
8. Антон Стеклов (asved.ru) 33 12.01.17 15:58 Сейчас в теме
10. Евгений Абдуразаков (asdfgcom) 106 12.01.17 18:04 Сейчас в теме
(6) Как говорится, спасибо за спасибо.
Что Вы подразумевали под: "Что же делать под Linux?"
COMобъекты может и устарели, но с ними легко быстро не зная ничего кроме 1С и протокола или описания методов начать работать над задачей.
К данной работе я подходил около месяца. Пытался сначала "врапить" по технологии NET, однако знаний не хватало и времени. По протоколу через winsocket надоумил сам производитель оборудования. Уже через неделю описал все команды, через 3 недели готовый прототип обмена. Сейчас "пилю" интерфейс, засовываю в расширение (для этого и понадобились параметры сеанса). К сожалению придется добавлять регистр сведений, синхронизировать его с данными из контроллера.
11. Павел Одинцов (Darklight) 5 12.01.17 18:16 Сейчас в теме
(10)Как работать сокeтами под Linux
12. Евгений Абдуразаков (asdfgcom) 106 12.01.17 18:30 Сейчас в теме
(11) 1С у заказчика под Windows. Однако, в свете последних событий и импортозамещения, придется скоро осваивать не только сокеты под Linux.
14. Евгений Абдуразаков (asdfgcom) 106 28.01.17 12:23 Сейчас в теме
В данный момент отказались от использования WinSocket и работой с контроллером непосредственно из 1С. 1С работает с контроллером очень медленно. На "слабых" машинах приходится полностью отключать автоматический опрос, т.к. обработчики событий начинают подавать команды не по очереди, а одновременно из-за медленной обработки событий и задач. Создавать кэш команд не хочется, решили всю низкую часть перенести на java.
Однако, для простых запросов вышеописанный способ общения может пригодиться.
15. Денис Володин (vdenu) 01.03.17 17:21 Сейчас в теме
Спасибо за статью, но вероятно я невнимательно её изучил и так и не понял два вопроса:
1. Каким же образом COM-объект созданный на сервере и затем помещённый в структуре во Временное хранилище может стать доступным на стороне клиента? ПолучитьИзВременногоХранилища() не срабатывает со стандартной ошибкой "Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа" Т.е. программа знает, что в структуре я "спрятал" com
2. Если я создаю Винсокет на стороне сервере, то как использовать ДобавитьОбработчик?
16. Евгений Абдуразаков (asdfgcom) 106 01.03.17 19:01 Сейчас в теме
(15)
1. Идя не нова, "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"

Контроллер = Новый COMОбъект("mswinsock.winsock");
.......

СтруктОбъекта = Новый Структура("Контроллер",Контроллер);
ПараметрыСеанса.Z5=ПоместитьВоВременноеХранилище(СтруктОбъекта,Новый УникальныйИдентификатор());

Помещаем в параметры сеанса, чтобы можно было дотянуться.
(мне нужно было, чтобы можно было использовать и на стороне конфигурации и на стороне расширения.)

2. Второй способ реализован в данный момент.

Следующим сообщением (вставка кода не работает)

17. Евгений Абдуразаков (asdfgcom) 106 01.03.17 19:14 Сейчас в теме
Вынес все в клиент. Только в этом случае работают обработчики событий. Объявил переменную Контроллер. Ограничил весь функционал одной обработкой.

Прошу прощения, не работает нормально вставка кода...

&НаКлиенте
Функция ВыполнитьПодключениеККонтроллеру()
	Попытка
		Контроллер = Новый COMОбъект(Объект.AddINКомпоненты); 
		ПараметрыКонтроллера = Новый Структура("Адрес, Порт");
		ПараметрыКонтроллера.Адрес = Объект.АдресПодключения;
		ПараметрыКонтроллера.Порт = Объект.ПортПодключения;
		
		Если Контроллер.State <> 7 тогда
			
			Если Контроллер.State <> 0 Тогда
				Контроллер.Close();
			КонецЕсли;
			
			Контроллер.RemoteHost = СокрЛП(ПараметрыКонтроллера.Адрес);
			Контроллер.RemotePort = СокрЛП(ПараметрыКонтроллера.Порт);
			
			Контроллер.Connect();
		Иначе
			Контроллер.Close();
			
			Контроллер.RemoteHost = СокрЛП(ПараметрыКонтроллера.Адрес);
			//		ws.RemoteHostIP = СокрЛП(ПараметрыПодключения.Адрес);
			Контроллер.RemotePort = СокрЛП(ПараметрыКонтроллера.Порт);
			
			Контроллер.Connect();
		КонецЕсли;
		
		ДобавитьОбработчик Контроллер.Connect, Connect; 
		ДобавитьОбработчик Контроллер.ConnectionRequest, ConnectionRequest; 
		ДобавитьОбработчик Контроллер.DataArrival, DataArrival;
		ДобавитьОбработчик Контроллер.Error, WinSocketError;
		
			Возврат Истина;
	Исключение
		Возврат Ложь;	
	КонецПопытки;
КонецФункции
Показать

Платформа: 8.3.9.1850
18. Денис Володин (vdenu) 02.03.17 09:29 Сейчас в теме
(17) Да, на клиенте действительно работает, а на сервере технология не живёт и ком-объект в хранилище хранится только для сервера, никакая упаковка не позволяет его получить на клиенте из хранилища, увы. Кстати, спасибо за статью - подтолкнула к экспериментам.
19. Евгений Абдуразаков (asdfgcom) 106 02.03.17 11:00 Сейчас в теме
(18) Настойчиво рекомендую почитать: "Хранение COM Объектов на Сервере ТонкогоКлиента Как сохранить COM-объект на Сервере между СервернымиВызовами. Автор статьи: H A D G E H O G s"
20. Елена Пименова (Bukaska) 125 02.03.17 11:16 Сейчас в теме
(17)Да почему.. вставка кода работает. Выделили текст и нажали на значок: </> - и готово
21. Евгений Абдуразаков (asdfgcom) 106 02.03.17 14:57 Сейчас в теме
(20) У меня браузер Chrome. Иногда (не всегда) после нажатия на </> не открывается форма вставки кода, а появляется то же окно редактирования сообщения, только без набранного текста. Не разобрался пока в чем дело.
22. Денис Володин (vdenu) 02.03.17 15:10 Сейчас в теме
Евгений, я недостаточно точно выразился. Вот ваша цитата: "Как же его хранить? Будем хранить его в параметрах сеанса. Оттуда он доступен и клиенту и серверу. " Хранить в структуре его (ComОбъект) можно, но доступен он всегда только для сервера и никогда для клиента. (Соответственно в случае с winsocket подобное решение лишено смысла)
23. Евгений Абдуразаков (asdfgcom) 106 02.03.17 18:48 Сейчас в теме
Оставьте свое сообщение