IE2017

Работа с Windows Sockets в 1С Предприятие.

Программирование - Внешние компоненты

При интеграции 1С:Предприятие с другими системами возможны случаи когда работа возможна только по протоколам TCP\IP или UDP. Платформа 1С не предоставляет механизмов для прямого взаимодействия с этими протоколами, что крайне неудобно, но, тем не менее, не невозможно.
Для работы с этими протоколами в среде Windows предназначена технология Windows Sockets.  
Реализует эту технологию  библиотека Mswinsock.dll (Mswinsock.ocx).

В качестве транслятора в протоколы TCP\IP или UDP данных из (в) 1С:Предприятие можно использовать ActiveX компоненту, входящую в состав библиотеки Mswinsock.dll.

Эта библиотека входит в состав пакета Visual Basic который можно установить вместе с пакетом программ MS Office. Ну или найти в Интернете.

Её полноценное использование в среде 1С:Предприятие возможно только в качестве ActiveX элемента на форме.

03_02_1 03_02_2

 

На форме появится значок с двумя компьютерами, примерно такой (все зависит от используемой вами операционной системы и версии библиотеки).

03_02_3_copy

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

03_02_6

После добавления компонента на форму становятся доступными все связанные с ним свойства и события. Наиболее часто используемые события добавляются на форму свойств.

События и свойства

Остальные свойства и события доступны через контекстную подсказку "IntelliSense" в модуле формы.

Контекстная подсказка

 

Свойства.

Из дополнительных свойств стоит отдельно выделить свойство "State" в это свойство содержит числовое значение текущего состояния компоненты - Статус.

Список возможных значений

Состояние Числовое значение Описание
sckClosed 0 Default. Closed
Значение по умолчанию. Подключение закрыто.
sckOpen 1 Open
Подключение активно. Соединение установлено.
sckListening 2 Listening
Режим "прослушки". Компонента ждет подключение по указанному порту.
sckConnectionPending 3 Connection pending
Ожидание подключения
sckResolvingHost 4 Resolving host
Получение адреса компьютера (хоста) по имени.
sckHostResolved 5 Host resolved
Адрес компьютера получен.
sckConnecting 6 Connecting
Подключение
sckConnected 7 Connected
Подключен
sckClosing 8 Peer is closing the connection
Клиент закрыл подключение
sckError 9 Error
Ошибка

Свойство Protocol содержит числовой параметр, указывающий, с каким протоколом работать. Protocol принимает одно из двух возможных значений

  • 0 - протокол TCP/IP
  • 1 - Протокол UDP

Свойство LocalPort числовой параметр, указывающий, какой порт будем прослушивать функцией Listen().

Свойства RemotePort и RemoteHost - это параметры, указывающие по какому адресу (IP или DNS) и на какой порт совершать подключение к серверу функцией Connect().

Для каждого параметра есть одноименная функция, которая возвращает текущее значение параметра или устанавливает новое значение. За исключением параметра State, для разработчика этот параметр ReadOnly.

 

Доступные события.

Error - Событие возникает при возникновении какой-либо ошибки.

Процедура WinSocketError(Элемент, Number, Description, Scode, Source, HelpFile,HelpContext, CancelDisplay)

    Сообщить(Description);

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

В параметрах события возвращается

  • Number - цифровой код возникшей ошибки,
  • Description - текстовое описание ошибки,
  • Scode - код ошибки в типе Long (HRESULT) SCODE
  • Source - описание источника ошибки,
  • HelpFile - ссылка на Файл справки
  • HelpContext - контекст файла справки
  • CancelDisplay - флаг отмены отображения стандартного окна об ошибке. По умолчанию значение - Истина. Окно не выводится.

DataArrival - возникает при поступлении данных.

Процедура WinSocketDataArrival(Элемент, bytesTotal)

   
ТкстСообщения = "";
   
WinSocket1.GetData(ТкстСообщения);
   
Сообщить("Получен ответ" + Символы.ПС + ТкстСообщения);

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

В параметр bytesTotal передается числовое значение, сколько байт было принято. Сами данные можно получить функцией GetData(). В параметр этой функции нужно передать строковую переменную, в которую функция вернет полученные данные.

Connect - событие возникает при успешном подключении к серверу. Возникает только на стороне клиента.

Процедура WinSocketConnect(Элемент)

    Сообщить("Покдлючение к " + Элемент.RemoteHost + " успешно.");

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

Это событие не имеет собственных параметров.можно работать только с параметрами самой компоненты.

ConnectionRequest - серверное событие, возникает при поступлении запроса на подключение.

Процедура WinSocketConnectionRequest(Элемент, requestID)

    Сообщить("Запрос подключения");

    Сост = "Подключение";

    Если НЕ
WinSocket.State = 0 Тогда
        WinSocket.Close()
    КонецЕсли;

    WinSocket.Accept(requestID);

    Сообщить("Приконнектился "+WinSocket.RemoteHostIP);

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

В параметр requestID поступает идентификатор подключаемого клиента. При этом, обратите внимание, что перед разрешением на подключение функцией Accept(requestID) необходимо компоненту перевести в состояние "0", т.е. закрыть открытый прослушиваемый поток.

Тут же можем получить IP-адрес подключаемого клиента из параметра RemoteHostIP.

Теперь, после установления соединения, можем передавать данные в обе стороны.

Close - Событие, возникающее при вызове метода Close() т.е. при закрытии компоненты.

SendProgress - Событие, возникающее при передаче данных, возникает при каждом переданном байте - так что не стоит навешивать слижком громоздкую или ресурсоемкую логику. Да и как показала практика, в 1С это событие использовать нет смысла, потому как процедура, связанная с этим событием, срабатывает только 1 раз, когда форма получает обратно фокус ввода.

Следующая процедура выводит прогресс отправки в окно служебных сообщений. По сути должна выводить сообщение для каждого отправленного байта. Но следующая картанка показывает что это не так.

Процедура WinSocketSendProgress(Элемент, bytesSent, bytesRemaining)

    Сообщить("Байт отправленно - " + bytesSent + "/ байт осталось - " + bytesRemaining);

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

Из картинки видно, что вызов процедуры произошел только один раз.

Результат вызова процедуры

 

SendComplete - Событие, возникающее при завершении отправки данных. Следующий код демонстрирует функционирование данного события.

Процедура WinSocketSendComplete(Элемент)

    Сообщить("-----------------------------------");
    Сообщить("" + + ТекущаяДата() + " |Отправка данных завершена! ");
    Сообщить("-----------------------------------");

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

Ну и сам результат вызова.

Пример вызова события

 Оригинал статьи на nastroy-ka.ru

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

Наименование Файл Версия Размер
Внешние обработки WinSocks Сервер и клиент
.rar 8,94Kb
07.03.12
179
.rar 8,94Kb 179 Скачать

См. также

Комментарии
0. Андрей Окипний (DMSDeveloper) 114 09.03.12 01:55 Сейчас в теме
При интеграции 1С:Предприятие с другими системами возможны случаи когда работа возможна только по протоколам TCP\IP или UDP. Платформа 1С не предоставляет механизмов для прямого взаимодействия с этими протоколами, что крайне неудобно, но, тем не менее, не невозможно.
Для работы с этими протоколами в среде Windows предназначена технология Windows Sockets.
Реализует эту технологию библиотека Mswinsock.dll (Mswinsock.ocx).

В качестве транслятора в протоколы TCP\IP или UDP данных из (в) 1С:Предприятие можно использовать ActiveX компоненту, входящую в состав библиотеки Mswinsock.dll.

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

1. Олег Филиппов (comol) 2971 09.03.12 12:22 Сейчас в теме
Полезно. Сама идея не нова - было в книге "1С. Системное программирование". Но там всё в коде создавалось и менее подробно описано. Однозначно "+", сам через ВК с сокетами работал, если бы раньше наткнулся...
2. Padonak-XXI (DMSDeveloper) 09.03.12 20:15 Сейчас в теме
А раньше статьи и не было. я сам решил написать стать только когда сам с этим столкнулся.
В этом способе есть одна сушественная проблема. еслисоздавать сервер на стороне 1С то сервер принимает только одно подключение. Создать стек серверов из одной компоненты, как это делается в примерах для C# или VB. тут не получится, а жаль.
3. zavedeev (zavedeev) 10.03.12 00:31 Сейчас в теме
Автор, молодец, что довел до народа данный принцип. Правда сервер на до писать на чем то продвинутом например на делфи, или компоненту писать с сервером.
zazaka; DMSDeveloper; +2 Ответить 1
4. Padonak-XXI (DMSDeveloper) 10.03.12 10:13 Сейчас в теме
(3) zavedeev, Я с вами согласен, но не полностью. Если сервер поддерживать так же мне, а я кроме 1С больше ни одного языка программирования толком не знаю и реализация сервера займет очень длительный период, не говоря уже о не опртимальном коде. То мне проще реализовать все на платформе 1С. Тем более, что производительность платформы по сравнению с ВК не так уж и отличается. ВК несомненно быстрее и стабильнее, хотя, как мне кажется это превосходство в рамках прогрешности инструмента замера производительности, да и стабильность зависит ом уровня программиста, реализовавшего ВК.

Я считаю, что при таких мизерных различиях реализация сокетов на платформе 1С имеет больше преимуществ чем ВК. Взять хотя бы открытость кода.
P.S. В ближайшее время на суд обществености предоставлю конфу которая как раз и реализует своеобразный мультиканальный Socket's-проксисервер.
5. zavedeev (zavedeev) 11.03.12 13:55 Сейчас в теме
Padonak-XXI, с большим удовольствием буду ждать конфу!
6. Александр Кулешов (Aragorn) 12.03.12 07:11 Сейчас в теме
7. Сергей (sstar90) 12.03.12 13:21 Сейчас в теме
Спасибо, статья интересная
8. Александр Милютин (sanfoto) 466 12.03.12 14:32 Сейчас в теме
Статья интересная, но таки серверную часть на 1С наверное не стоит делать.
Отправить данные(клиент)- да, но сервер ожидающий прихода данных из вне(например в бесконечном цикле).... это на 1С реализовать мне кажется нормально не получится.))
Поэтому я писал свою ВК на C#, примеров в инте много, даже не зная языка мне это удалось за пару дней))
9. Padonak-XXI (DMSDeveloper) 12.03.12 14:50 Сейчас в теме
(8) sanfoto, Никаких бесконечных циклов тут и не требуется. Достаточно перевести компоненту в состояние Listen. И она будет ждать подключений до скончания века, ну или пока конфу не закроют :)

И такой закономерный вопрос: Зачем писать ВК для работы с другой ВК?
10. Олег (oleg_km) 15.03.12 12:44 Сейчас в теме
Давно использую этот АктивИкс, только он входит не в состав библиотеки Mswinsock.dll. Он входит в состав MS Visual Studio 6 как компонент Visual Basic - Mswinsck.ocx
11. Padonak-XXI (DMSDeveloper) 15.03.12 15:22 Сейчас в теме
(10) oleg_km,
Может быть, спорить не буду.
12. Олег (oleg_km) 15.03.12 15:57 Сейчас в теме
Не нужно спорить, просто уточнил, где его можно взять, он же с операционкой не устанавливается
13. Padonak-XXI (DMSDeveloper) 15.03.12 17:25 Сейчас в теме
(12) oleg_km, он по моему устанавливается вместе с офисом. Потому как у меня на работе более никакого Visual Basic нет.
Исправлю в статье информацию о том где взять компоненту.
14. Олег (oleg_km) 15.03.12 18:23 Сейчас в теме
Ну тогда нужно с этим разобраться и дать в статье информацию, где его брать. Мы этот компонент сами ставим на каждый новый компьютер при его начальной настройке
15. Mir-mup (Mir-mup) 16.03.12 10:14 Сейчас в теме
16. Ийон Тихий (cool.vlad4) 41 16.03.12 12:11 Сейчас в теме
(11) не может быть, а так точно. является частью проприетарного ПО, поэтому на обычном компе без васика, ее(библиотеки) нет. Для её регистрации требуется внести лицензионный ключ в реестр. Сама библиотека - обычный com сервер, поэтому вовсе необязательно для этого использовать форму/activex.
17. Padonak-XXI (DMSDeveloper) 16.03.12 13:57 Сейчас в теме
(16) cool.vlad4, Использование именно в режиме ActiveX позволяет работать с событиями самой компоненты, а не отслеживать состояния через бесконечные циклы (пример использования цикла с проверкой параметра State можно найти в книге 1С:Предприятие 7.7/8.0 Системное программирование. Стр. 20). Причиной невозможности работать с событиями в режиме Com-автоматизации является то, что все методы у библиотеки асинхронные. Соответственно, поймать изменение состояния можем либо через цикл, постоянно считывая параметр State, либо перехватывая соответствующее событие на форме.
Еще одним преимуществом использования событий по сравнению с Com-сервером, вижу то, что 1С не "зависает" отслеживая циклами изменение состояния.
18. Ийон Тихий (cool.vlad4) 41 16.03.12 14:13 Сейчас в теме
(17) я прекрасно работал с winsock как с com сервером и с событиями. Добавляются события через стандартную ф-цию ДобавитьОбработчикСобытия.
19. Ийон Тихий (cool.vlad4) 41 16.03.12 14:16 Сейчас в теме
Функция СоздатьОбъект() Экспорт

Попытка
ws = Новый COMОбъект("mswinsock.winsock");
Исключение

Возврат Ложь;

КонецПопытки;

//Попытка
ДобавитьОбработчик ws.Close, Close;
ДобавитьОбработчик ws.Connect, Connect;
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest;
ДобавитьОбработчик ws.DataArrival, DataArrival;
ДобавитьОбработчик ws.Error, Error;
ДобавитьОбработчик ws.SendComplete, SendComplete;
ДобавитьОбработчик ws.SendProgress, SendProgress;
//Исключение
//КонецПопытки;

Возврат Истина;
20. Ийон Тихий (cool.vlad4) 41 16.03.12 14:19 Сейчас в теме
Со State там я помню была другая трабла, но я видел как-то тему на мисте, где описывалось решение. сейчас не помню, поскольку этим винсоком уже не пользуюсь. ну его нафиг.
21. Padonak-XXI (DMSDeveloper) 16.03.12 21:43 Сейчас в теме
(19) cool.vlad4, Опачки... Век живи - век учись. я и не знал о возможности привязки обработчиков.
Спасибо за пример.
22. Александр Киричков (Bezeus) 26.03.12 04:11 Сейчас в теме
Как же мне не хватало этой статьи год назад... Вы просто представить не можете - сколько времени я мог бы сэкономить... Теперь это попробую уже не для проекта, а для собственных "глупостей" навроде управлением из 1С всякими ничтяками ) Огромное спасибо автору!
23. Padonak-XXI (DMSDeveloper) 26.03.12 21:00 Сейчас в теме
24. Jani V (jeniav) 27.03.12 08:43 Сейчас в теме
Спасибо! Интересная информация
25. Сергей Самсонов (barcoder) 31.07.12 03:50 Сейчас в теме
Скачал данную обработку. Не работает. Ругаеться на поле объекта.
Библиотека зарегистрирована в элементах ActiveX отображаеться нормально.
Что нибудь надо дописывать?
{Форма.Форма.Форма(5)}: Поле объекта не обнаружено (State)
Если WinSocket.State <> 0 тогда
26. Padonak-XXI (DMSDeveloper) 13.08.12 10:25 Сейчас в теме
(25)Вообще-то ничего дописывать не надо. Обработки рабочие. Проверялось на Win XP в режиме домена, Win 7 HP, Win Server 2008 и Win Server 2008 R2.
Попробуйте в режиме отладки проверить, что находится в объекте WinSocket, скорее всего у вас не создается COM-объект.
27. dskull86 Алексеев (dskull86) 17.10.12 15:51 Сейчас в теме
кто нибудь перепишет на управ. приложение
35. Андрей Окипний (DMSDeveloper) 114 21.01.13 10:29 Сейчас в теме
(34) Да не за что извиняться, бывает оппоненты и на эмоциях ведут дискуссию.
Относительно вашего замечания по использованию технологий .Net - полностью с вами согласен! Но я не спец по этой технологии и написать соответствующую ВК не в состоянии, нужно потратить много времени на изучение, а нужно было здесь и сейчас, вот и пришлось использовать то, что есть.
36. Вадим Янчук (vadimlp77) 26 30.01.13 14:45 Сейчас в теме
Помогите плиз, дайте саму компоненту, не могу найти то, что нужно под win 2008 server 64.
37. Андрей Окипний (DMSDeveloper) 114 30.01.13 18:08 Сейчас в теме
(36)Под win 2008 server 64 компоненты не существует, нужно использовать старую (под X86) найти саму компоненту с инсталятором не сложно.
Как старую компоненту заставить работать на X64 показано на видео
Загрузка плеера
38. Вадим Янчук (vadimlp77) 26 30.01.13 18:16 Сейчас в теме
(37) DMSDeveloper, спасибо большое. А можешь мне ссылочку на работающую компоненту дать ? Я нашел каких то две с одинаковым названием и абсолютно разынм размером: 10 мб и 100 кб. И еще вопросик .. Как их регистрировать ? regsvr32 ругнулся на них. Достаточно их просто пометсить в System32 или что то еще нужно делать кроме того, что на видео ? Спасибо !
39. Андрей Окипний (DMSDeveloper) 114 30.01.13 18:26 Сейчас в теме
(38) Я использую вот эту сборку
winsock_x64.rar
vsozansky; lionnoiL; +2 Ответить 1
40. Вадим Янчук (vadimlp77) 26 30.01.13 18:35 Сейчас в теме
(39) DMSDeveloper, спасибо огромное, буду пробовать. С поддержкой многопоточности всё ок ? У меня будет до 200-х устройств, которые будут слать пакеты раз в 30 сек. Можно, конечно, разбить по портам 1с-ки (например по 40 устройств на один порт) и запустить 5 1с-ок. Как думаешь? Есть такой опыт ?
41. Leo Z (Leon99) 30.01.13 18:56 Сейчас в теме
да, спасибо, интересная статья
42. Leo Z (Leon99) 30.01.13 18:56 Сейчас в теме
будут подобные посты еще ?
43. Андрей Окипний (DMSDeveloper) 114 31.01.13 13:06 Сейчас в теме
(40) В выложенном примере многопоточности нет. В "классическом" приложении многопоточность организуется формированием массива из инициализированных mswinsck, для этого при инициализции устанавливается параметр компоненты index. 1С, к сожалению, этот параметр не видит и работать с ним отказывается.
Я эту проблему решил следующим образом
1. создаю обработку "прослушку" предопределенного порта
2. когда на порт поступает входящий запрос создаю инстанс обработки "proxy" в которой назначаю новый порт и передаю этот порт клиенту с требованием переподключиться на него.
3. "Прослушку" опять перевожу в режим прослушки на предопределенный порт.
Вот пример MswinSock-Proxy
В примере нет справки и код не причесан, но суть понять можно.
vsozansky; Rokky78; +2 Ответить 3
44. Андрей Окипний (DMSDeveloper) 114 31.01.13 13:08 Сейчас в теме
(41)
Не за что.

(42)
Пока ничего такого специфического на работе не попалось, так что пока не будет.
45. Антон (Lantastic) 28.06.13 14:03 Сейчас в теме
Спасибо за полезную статью.

(43)
По многопоточности. Теоретически можно подойти к вопросу еще одним образом. Программно разместить на форме требуемое количество невидимых экземпляров ActiveX WinSock в соответствии с количеством портов, требующих прослушки. Программно назначить им одни и те же процедуры-обработчики событий. При этом в каждую процедуру при наступлении события будет платформой передаваться соответствующий экземпляр компоненты в параметр "Элемент", т.о. мы сможем всегда определить от какого экземпляра пришло событие и обработать его соответствующим образом.
Как Вам такая идея реализации?
46. Андрей Окипний (DMSDeveloper) 114 01.07.13 10:02 Сейчас в теме
(45) Lantastic, Для использования разных портов такой вариант возможен. Но, если вам нужен пул коннектов на одном порту, такой вариант не проканает. Платформа 1С не поддерживает индексы.

подробнее про индексы в (43).

А если посмотреть на пример из (19) то необходимость создавать компоненты на форме отпадает сама собой. И приведенные примеры можно организовывать на стороне сервера.
Использование компоненты на стороне сервера сразу решает вопрос использования компоненты в управляемых формах.
Это решение вопроса для (27)
47. Антон (Lantastic) 01.07.13 15:57 Сейчас в теме
(46) Да, вполне согласен, мой вариант для параллельной прослушки набора портов, а не получения пула на один порт от разных.
Но если нужно прослушивать много портов, подход в (19) усложняет жизнь. Если мы назначим программно события, мы в событии не узнаем каким конкретно экземпляром оно рождено. Либо создавать наборы событий для каждого экземпляра, но это не всегда гибко.
48. Андрей Окипний (DMSDeveloper) 114 01.07.13 18:12 Сейчас в теме
Для параллельной прослушки набора портов ваш способ наилучшее решение.
А из (19) можно взять реализацию программного создания экземпляра библиотеки с привязкой процедур в модуле объекта, а не на форме - позволит работать на стороне сервера в фоне.

Пример

Попытка

ws = Новый COMОбъект("mswinsock.winsock");
ДобавитьОбработчик ws.Close, Close;
ДобавитьОбработчик ws.Connect, Connect;
...

КонецПопытки;

Попытка

ws_2 = Новый COMОбъект("mswinsock.winsock");
ДобавитьОбработчик ws_2.Close, Close_2;
ДобавитьОбработчик ws_2.Connect, Connect_2;
...
КонецПопытки;
vsozansky; +1 Ответить
49. Антон (Lantastic) 13.07.13 17:18 Сейчас в теме
Коллеги!
Есть проблема в Winsock.
На Windows server 2008 32-bit компонента не работает нормально.
При размещении ActiveX объекта на форме добавляется новый элемент, но в палитре свойств нет его специфических свойств и событий. Программно тоже не видит свойства и методы.
На Windows XP работает нормально.
На Windows 7 такая же проблема.
Может, кто сталкивался с проблемой?
50. Антон (Lantastic) 14.07.13 11:54 Сейчас в теме
(49)Разобрались. Оказывается одного mswinsck.ocx файла с компонентой не достаточно. Пока точно не выяснили, что именно еще требуется, чтобы ActiveX виделся в 1С правильно. Но помогла установка пакета ActiveX из дистрибутива Visual Basic 6.
51. Андрей Окипний (DMSDeveloper) 114 01.10.13 13:05 Сейчас в теме
(50) Странно, мне хватило только двух файлов и записи ключа в реестр.
1.MSWINSCK.ocx
2.license.reg
3.mswsock.dll - это стандартная библиотека Windows

Ключик из license.reg
[HKEY_CLASSES_ROOT\Licenses\2c49f800-c2dd-11cf-9ad6-0080c7e7b78d]
@="mlrljgrlhltlngjlthrligklpkrhllglqlrk"
52. Alexey (zarius) 145 15.04.14 18:15 Сейчас в теме
(0) а не сталкивались с ситуацией когда надо принимать двоичные данные? По идее GetData корректно получает двоичные данные от сервера, но вот как корректно их принять в 8ке?
53. Юрий Троцкий (tro2001) 12.06.15 09:26 Сейчас в теме
Здравствуйте. А можно каким-то образом на WinSock послать не строковое значение, а байт кодировки HEX (шестнадцатиричный) ?. Т.е. нужно послать что-то типа 0x1F.
54. Александр Плюшкин (php5) 9 25.06.15 15:26 Сейчас в теме
Добрый день!

А подскажите пож-а, в фоновом задании программно создаю WinSock, подключаюсь как положено через Connect(), назначаю для него событие "ДобавитьОбработчик ws.Connect, Connect" кручу бесконечный цикл, а в событие не падает? Почему? Возможно ли вообще реализовать вызов внешних событий в фоновом задании?

При использовании того же когда на клиенте, все работает ок.
55. Юрий Троцкий (tro2001) 09.07.15 16:22 Сейчас в теме
Попытка	
ws = Новый COMОбъект("mswinsock.winsock"); 
Исключение 

Возврат Ложь; 

КонецПопытки; 

//Попытка 
ДобавитьОбработчик ws.Close, Close; 
ДобавитьОбработчик ws.Connect, Connect; 
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest; 
ДобавитьОбработчик ws.DataArrival, DataArrival; 
ДобавитьОбработчик ws.Error, Error; 
ДобавитьОбработчик ws.SendComplete, SendComplete; 
ДобавитьОбработчик ws.SendProgress, SendProgress; 
//Исключение 
//КонецПопытки;
...Показать Скрыть


Пишет, что "Метод объекта не обнаружен"...ни один...в чем может быть проблема ?

С созданным на форме объектом работало нормально, но нужно создавать программно, а я не могу назначить ему обработчики событий.
56. Юрий Троцкий (tro2001) 09.07.15 16:40 Сейчас в теме
Попытка    
ws = Новый COMОбъект("mswinsock.winsock"); 
Исключение 

Возврат Ложь; 

КонецПопытки; 

//Попытка 
ДобавитьОбработчик ws.Close, Close; 
ДобавитьОбработчик ws.Connect, Connect; 
ДобавитьОбработчик ws.ConnectionRequest, ConnectionRequest; 
ДобавитьОбработчик ws.DataArrival, DataArrival; 
ДобавитьОбработчик ws.Error, Error; 
ДобавитьОбработчик ws.SendComplete, SendComplete; 
ДобавитьОбработчик ws.SendProgress, SendProgress; 
//Исключение 
//КонецПопытки;
...Показать
...Показать Скрыть


Пишет, что "Метод объекта не обнаружен"...ни один...в чем может быть проблема ?

С созданным на форме объектом работало нормально, но нужно создавать программно, а я не могу назначить ему обработчики событий.
57. Yuriy Galiev (jurgal1C) 16.11.15 04:34 Сейчас в теме
(49) Lantastic, у меня такая же проблема, установил пакет MS VB6 вместе с ActiveX, но не помогло, т.е. событий в палитре нет =(
58. Василий Васин (e322) 17.11.15 21:17 Сейчас в теме
У меня на 1с77 не работает
ДобавитьОбработчик ws.Connect, Connect;

Подскажите, пожалуйста, что можно сделать?
59. Александр (chilyagin) 81 18.11.15 11:59 Сейчас в теме
60. Александр (chilyagin) 81 18.11.15 12:01 Сейчас в теме
(54) php5,

Вы проверяли: комобъект winsock у вас создается в фоновом задании?
61. Дмитрий Пилипчук (Noxie41) 13.04.16 15:20 Сейчас в теме
У кого-то есть опыт работы с WinSocket на управляемых формах в тонком клиенте? Поделитесь.

При использовании кода через пару секунд (наверное на подключение) 1с просто ругает на Runtime и валится((


&НаСервере
Процедура СнятьTCPНаСервере()

	WinSock = Новый COMОбъект("MSWinsock.Winsock");

Если WinSock.State <> 7 Тогда
	
	Если WinSock.State <> 0 Тогда
		WinSock.Close();
	КонецЕсли;
	
	WinSock.RemoteHost = СокрЛП(Адрес);
	WinSock.RemotePort = СокрЛП(Порт);
	WinSock.Protocol = 0;
		
	WinSock.Connect();
		
КонецЕсли; 

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

КонецПроцедуры
...Показать Скрыть
63. Михаил Морокин (Rokky78) 15 26.05.16 13:49 Сейчас в теме
(43) DMSDeveloper, Спасибо за cf'ник. Помог победить печать на Штрих-600 с помощью ESC последовательностей и компоненты Windows Sockets из управляемого приложения.
64. Viacheslav Bilous (Gendalf_beliy) 08.07.16 18:57 Сейчас в теме
Если сервер поддерживать так же мне, а я кроме 1С больше ни одного языка программирования толком не знаю и реализация сервера займет очень длительный период, не говоря уже о не опртимальном коде. То мне проще реализовать все на платформе 1С. Тем более, что производительность платформы по сравнению с ВК не так уж и отличается. ВК несомненно быстрее и стабильнее, хотя, как мне кажется это превосходство в рамках прогрешности инструмента замера производительности, да и стабильность зависит ом уровня программиста, реализовавшего ВК.

Я считаю, что при таких мизерных различиях реализация сокетов на платформе 1С имеет больше преимуществ чем ВК. Взять хотя бы открытость кода.
P.S. В ближайшее время на суд обществености предоставлю конфу которая как раз и реализует своеобразный мультиканальный Socket's-проксисервер.

(4) Padonak-XXI, написали конфу уже?
65. ROM ROM (ROM_1C) 663 27.07.16 13:04 Сейчас в теме
Питаюсь отправить данные на tcp сервер с тонкого клиента.
Процедура на клиенте

Адрес="192.168.1.100";
	порт="6000";
	Попытка	
		WinSocket1 = Новый COMОбъект("MSWinsock.Winsock"); 
	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки; 
	//WinSocket1.Protocol =0;
	

	
	Если WinSocket1.State <> 7 тогда
		
		Если WinSocket1.State <> 0 Тогда
			WinSocket1.Close();
		КонецЕсли;
		
		WinSocket1.RemoteHost = СокрЛП(Адрес);
		WinSocket1.RemotePort = СокрЛП(Порт);
		
		WinSocket1.Connect();
			
	КонецЕсли;

	  Если WinSocket1.State = 7 тогда //Подключились удачно, отправляем данные
		
		WinSocket1.SendData("1234567");
	Иначе 
		Сообщить(  WinSocket1.State);
	КонецЕсли;
...Показать Скрыть



Статус постоянно 6. В какие-то моменты сервер принимает подключения, но самого сообщения нет.
Подскажите как решить проблему? спасибо!
66. ROM ROM (ROM_1C) 663 27.07.16 22:34 Сейчас в теме
(65) Разобрался. Нужно разделить подключение и отправку на 2 процедуры. + после отправки нужно закрывать соединение, так как посылка не уходит. Не уходить причем и на толстом и на тонком клиенте
67. Андрей Окипний (DMSDeveloper) 114 25.08.16 14:10 Сейчас в теме
(64) Gendalf_beliy,
Нет, отпала в ней необходимость.
68. Александр К (a-v-k-23) 21.10.16 11:15 Сейчас в теме
(66) ROM_1C, Разделил подключение и отправку на две процедуры. Процедуру получения выполняю НаСервере. Ничего не получаю. Хотя подключение происходит.
Подскажите, как у вас реализовано?
На форме поле есть?
70. Евгений Абдуразаков (asdfgcom) 99 09.01.17 12:46 Сейчас в теме
Прикручиваем к УФ:
ActiveX нельзя, поэтому подключаем COMобъект и храним его в параметрах сеанса:
Процедура ПриОткрытииНаСервере()
	Контроллер = Новый COMОбъект("mswinsock.winsock"); 
	ПараметрыКонтроллера = Новый Структура("Адрес, Порт");
	ПараметрыКонтроллера.Адрес = "xxx.xxx.xxx.xxx";
	ПараметрыКонтроллера.Порт = "pppp";
	
	СтруктОбъекта = Новый Структура("Контроллер",Контроллер);
	ПараметрыСеанса.Z5=ПоместитьВоВременноеХранилище(СтруктОбъекта,Новый УникальныйИдентификатор());
	ИнициализироватьПодключение(ПараметрыКонтроллера);
КонецПроцедуры

//------------------------------------------

&НаСервере
Процедура ИнициализироватьПодключение(ПараметрыПодключения)	
	ws = ПолучитьИзВременногоХранилища(ПараметрыСеанса.Z5).Контроллер;
	//	ws = Новый COMОбъект("mswinsock.winsock"); 	
	Если ws.State <> 7 тогда
		
		Если ws.State <> 0 Тогда
			ws.Close();
		КонецЕсли;
		
		ws.RemoteHost = СокрЛП(ПараметрыПодключения.Адрес);
		//		ws.RemoteHostIP = СокрЛП(ПараметрыПодключения.Адрес);
		ws.RemotePort = СокрЛП(ПараметрыПодключения.Порт);
		
		ws.Connect();
	Иначе
		ws.Close();
		
		ws.RemoteHost = СокрЛП(ПараметрыПодключения.Адрес);
		//		ws.RemoteHostIP = СокрЛП(ПараметрыПодключения.Адрес);
		ws.RemotePort = СокрЛП(ПараметрыПодключения.Порт);
		
		ws.Connect();
	КонецЕсли;
	Объект.Статус = ws.state; //передаем статус отображаем его на форме
	
КонецПроцедуры

//Событие DataArrival недоступно! Поэтому создаем тандемом 2 обработчика ожидания:
//Отправка команды, ниже ожидание ответа:

&НаКлиенте
Процедура ВыполнитьКоманду()
	
	ПолучитьСтатус();
	Элементы.Статус.Заголовок = Объект.Статус;
	Если Объект.Статус = 0 Тогда   //Не подключено 
		ПриОткрытииНаСервере();
		Возврат;
	ИначеЕсли Объект.Статус = 6 Тогда // еще идет подключение
		Возврат;
	КонецЕсли;
	УправлениеДоступностью(Ложь); //ничего нельзя делать на форме
	Результат = ОтправитьДанные();   // Ниже функция отправки
	Элементы.Статус.Заголовок = Объект.Статус;
	Если Результат Тогда
		Объект.Лог = Формат(ТекущаяДата(),"ДЛФ=DT") + ": " + Объект.Команда +" --> " + Символы.ПС + Объект.Лог;
		Объект.Лог = Объект.ТекстСообщения + Символы.ПС + Объект.Лог;
		ОтключитьОбработчикОжидания("ВыполнитьКоманду"); //Команда выполнилась, отключаем этот обработчик
		ПодключитьОбработчикОжидания("ПолучитьОтвет",1); //Подключаем ожидание ответа Многократно	
	Иначе
		Если Объект.Статус = 9 Тогда //ошибка, не расшифровать нафиг
			ПриОткрытииНаСервере(); //реконнект (кстати не помогает. Только отключение кабеля)
		КонецЕсли;
	КонецЕсли;   	
	
КонецПроцедуры

// Ежесекундная проверка ответа

&НаКлиенте
Процедура ПолучитьОтвет()
	Элементы.Статус.Заголовок = Объект.Статус;
	Результат = ПолучитьОтветНаСервере(); //ф-я ниже	
	Элементы.Статус.Заголовок = Объект.Статус;
	Если Результат Тогда
		ОтключитьОбработчикОжидания("ПолучитьОтвет"); //ответ получен, отключаем обработчик
		Объект.Лог = Формат(ТекущаяДата(),"ДЛФ=DT") + ": " +Объект.Команда +" <-- " + Символы.ПС + Объект.Лог;
		Объект.Лог = Объект.ОтветКонтроллера + Символы.ПС + Объект.Лог;
		ВыполнитьОбработкуОтвета(); // Здесь много условий которые получают название команды и соответственно ее обрабатывают
	Иначе
		ПриОткрытииНаСервере();  /реконнект
	КонецЕсли;   	
	
КонецПроцедуры

//Отправляет данные через SendData()

&НаСервере
Функция ОтправитьДанные()
	Результат = Ложь;
	Контроллер = ПолучитьИзВременногоХранилища(ПараметрыСеанса.Z5).Контроллер; //получили winsocket из параметров сеанса
	buff = ПреобразоватьДляОтправки(Объект.ТекстСообщения);  // преобразование в массив HEX требуется для моего контроллера
	buff[0] = "&H" + Объект.ТипКоманды;
	ВОтправку = "";
	Для н = 0 По buff.Количество()-1 Цикл
		ВОтправку =ВОтправку + buff[н] + " ";	
	КонецЦикла;

	Объект.Статус = Контроллер.State;
	
	Если Контроллер.State = 7 тогда //Подключились удачно, отправляем данные
		Попытка
			Для н = 0 По buff.Количество()-1 Цикл
				Контроллер.SendData(Chr(buff[н])); // отправляю посимвольно из буфера  Chr(Код) - функция с VBScript которая преобразует из HEX в символ.
			КонецЦикла;
			Результат = Истина;
		Исключение
		КонецПопытки;
		
		
	КонецЕсли;	
	Возврат Результат;	
КонецФункции
...Показать Скрыть



Собственно, отправка команды:

Объект.ТипКоманды = "20";
	Объект.Команда = "ПолучитьАдресКонтроллера";
	Объект.ТекстСообщения = "00 08 08 01 00 00 00 00";
	ПодключитьОбработчикОжидания("ВыполнитьКоманду",1);

...Показать Скрыть


Функция обработки полученных ответов:

&НаКлиенте
Процедура ВыполнитьОбработкуОтвета()
//	БуферПриема = СтрокуВМассивы(Объект.ОтветКонтроллера);
	Если Объект.Команда = "ПолучитьАдресКонтроллера" Тогда
		М4 = ОтветВМассив();
		ФлагПриема = Истина;
		//Расшифруем полученные данные
		i = 8;
		Пока i < 20 Цикл
			текАдр = АдресКонтроллера(М4[i], i - 8);
			Если ТекАдр.Количество()>0 Тогда
				Для Каждого Эл Из ТекАдр Цикл
					Объект.СписокКонтроллеров.Добавить(Эл.Значение);
				КонецЦикла;
			КонецЕсли;
			i = i + 1;
		КонецЦикла;
		Объект.Команда = "";
	ИначеЕсли Объект.Команда = "СписокКарт" Тогда
..........................................
	КонецЕсли;
	УправлениеДоступностью(Истина);	
КонецПроцедуры

...Показать Скрыть



Медленно, но работает!!!
Надеюсь, кому-нибудь пригодится.

Есть мнение, кому не жалко немного времени, создать ВК с методами:
1. Подключить(Адрес,Порт) Возвращает Истина, Ложь
2. ОтправитьСтроку(Строка) Возвращает Истина Ложь
3. ПрочитатьОтвет() Возвращает ответы, накопленные в буфере Возможен вариант, В какой-либо переменной появляется ответ, который на стороне 1С можно прочитать и/или удалить, если прочитали
4. Отключить

Там строк 50 текста будет, которые повысят стабильность, избавят от асинхронности в 1С, которая требует обработчиков, которые работают 1 раз в секунду.

Понимаю, что можно было организовать иначе, но основное требование - минимум изменений. Добавлено в конфигурацию только: переменная Z5 в параметры сеансов
vsozansky; +1 Ответить
Оставьте свое сообщение