1C + jabber

Использование протокола xmpp для информационных сообщений из 1С без подключения внешних dll.

Не так давно в компании в которой я работаю, внедрили 1С:Документооборот.

Система хорошая (после выпуска версии 1.2.2.6) и нужная, спору нет.

Исторически так сложилось, что в компании развернут и используется jabber сервер.

Документооборот хорош всем, в том числе умеет рассылать уведомления на e-mail о поступивших новых задачах.

Да вот беда, с протоколом xmpp 1C работать не умеет.

Не проблема, берем в руки напильник!

 

Первой мыслью было использовать внешнюю компоненту от товарища Душелова.

Сказано — сделано.

 

Грабли №1:

При работе на сервере в виде регламентного задания сервер вешается намертво (ни одна база не отвечает до перезагрузки)

Грабли №2:

При попытке отправить сообщения со стороны клиента первые 2-4 сообщения уходят, затем сессия вешается, как и в случае сервера, но хотя бы можно убить сессию.

Внешнюю компоненту, выдернутую из демобазы СЭД Аналитикс постигла та же участь.

 

В причинах разбираться, не было ни времени, ни желания.

Или в компонентах проблема, или в сервере, или на сервере jabbera.

 

Поиски в интернете натолкнули на мысль о php.

 

Итак, рецепт.

 

Берем библиотеки http://webi.ru/webi_files/xmpp_webi.html

 

В файле config.ini.php прописываем настройки сервера, аккаунт для отправки и пр.

 

Кладем файлы config.ini.phpxml.class.php, xmpp.class.php в отдельную папку на сервере, на котором крутится 1С.

Например «\servere$AddInjabber»

На сервере устанавливаем php (если не установлен), настраиваем ассоциации для открытия php файлов.

 

Теперь возьмемся за конфигуратор.

 

Создаем общий модуль с настройками сервер и вызов сервера.

 

Напишем в нем функцию.

&НаСервере
Процедура ОтправитьСообщениеСервером(ТЗ, ИмяФайла) Экспорт
ТекТекст = Новый ТекстовыйДокумент;
ТекСтрока  = "; ТекТекст.ДобавитьСтроку(ТекСтрока);
ТекСтрока  = "include_once("+Символ(34)+"xmpp.class.php"+Символ(34)+");"; ТекТекст.ДобавитьСтроку(ТекСтрока);
ТекСтрока  = "$webi = new XMPP($webi_conf);"; ТекТекст.ДобавитьСтроку(ТекСтрока);
ТекСтрока  = "$webi->connect();"; ТекТекст.ДобавитьСтроку(ТекСтрока);

Для Каждого ТЗСтрока из ТЗ Цикл
АдресатJabber = СокрЛП(ТЗСтрока.АдресатJabber);
СообщениеJabber = СокрЛП(ТЗСтрока.СообщениеJabber);
ТекСтрока = "$webi->sendMessage("+Символ(34)+АдресатJabber+Символ(34)+", "+Символ(34)+СообщениеJabber+Символ(34)+");";
ТекТекст.ДобавитьСтроку(ТекСтрока);
КонецЦикла;

ТекСтрока  = "?>"; ТекТекст.ДобавитьСтроку(ТекСтрока);
Попытка
ТекТекст.Записать("\servere$AddInjabber"+ИмяФайла+".php","UTF-8");
sender= "\servere$AddInjabber"+ИмяФайла+".php";
ЗапуститьПриложение(sender);
Исключение
ЗаписьЖурналаРегистрации("Отправка в Jabber", УровеньЖурналаРегистрации.Ошибка, , "", "Отправка в jabber завершилась неудачей.");
КонецПопытки;
КонецПроцедуры

ТЗ это таблица значений с адресами в виде аккаунт@сервер и сообщениями.

ИмяФайла это имя файла который будет запущен php интерпретатором.

Вот и всё, регламентным заданием на сервере можно формировать таблицу с адресами и сообщениями и отправлять в jabber.

Решение может и не самое изящное, зато простое и работает.

30 Comments

  1. cool.vlad4

    А я для пыха использую http://code.google.com/p/xmpphp/

    — клиентам часто требуется организовать уведомления о заказах с интернет магазинов. Собственно jabber для этого очень даже.

    То, что xmpp компоненты вешают 1С, — возможная причина частый опрос клиентов сервером (на проверку соединения). Тут либо надо отключать это на сервере, либо урезать функционал компоненты. Другая причина — неправильное освобождение ресурсов(компонентой. либо в 1С коде не прописано). Из-за этого 1С вообще может крашится. На самом деле я рекомендую использовать jabber в 1С — только таким образом как у вас в статье (т.е. только для регламентных процедур — отправка сообщений по событию) — я как раз сейчас что-то такое и делаю. Для клиентов лучше использовать или какой-нибудь web клиент, либо Miranda. Для 1С-ки компонент можно использовать старый, но мне больше всех понравился — http://jabbercom.sourceforge.net/ — com server — документация, все есть(единственно, были замечены некоторые небольшие расхождения между ней и компонентой, видимо автор просто не обновил доки).

    Reply
  2. cool.vlad4

    мКлиентJabber = Новый COMОбъект(«JabberCOM.JabberSession»);

    ДобавитьОбработчик мКлиентJabber.OnConnect, OnConnect;

    ДобавитьОбработчик мКлиентJabber.OnMessage, OnMessage;

    ДобавитьОбработчик мКлиентJabber.OnException, OnException;

    ДобавитьОбработчик мКлиентJabber.OnCommError, OnCommError;

    ДобавитьОбработчик мКлиентJabber.OnAuthError, OnAuthError;

    ДобавитьОбработчик мКлиентJabber.OnXML, OnXML;

    ДобавитьОбработчик мКлиентJabber.OnXMLTag, OnXMLTag;

    ДобавитьОбработчик мКлиентJabber.OnDisconnect, OnDisconnect;

    ДобавитьОбработчик мКлиентJabber.OnRosterStart, OnRosterStart;

    и т.д. событий там до хера. Описание событий есть в доках. Например OnMessage — при поступлении сообщения. Также есть возможность внедрять свой xml код. В таком случае удобно событие

    Процедура OnXML(Direction, txt)

    // Direction = 0 —> Исходящие

    // Direction = 1 —> Входящие

    // dString = ?(Direction = 1 ,»SENT: «, «RECV: «);

    //Сообщить(dString + txt);

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

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

    Reply
  3. X.Leshiy

    Спасибо, попробую и этот вариант 🙂

    Reply
  4. Dimasik2007

    Если есть небольшие навыки по работе в Visual Studio, то можно написать свой джаббер-бот (тут)

    З.Ы. Мы шли одинаковыми путями)

    Reply
  5. sound

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

    Reply
  6. X.Leshiy

    Подключение да, медленное.

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

    Пока устраивает 🙂

    Reply
  7. KroVladS

    ЗапуститьПриложение(sender);

    Не работает в серверном режиме.

    Не пробовал конектить этот php класс с OpenFire+SSL?

    Reply
  8. X.Leshiy

    (7) KV1s, Что значит не работает? Замечательно работает. На сервере, где стоит 1С сервер, должен быть установлен php и задано соответствие для файлов с расширением .php.

    Я не знаю на чем у нас jabber крутится, по идее, должно работать на всех.

    Reply
  9. KroVladS

    (8)

    Конфигуратор выдаёт такую ошибку:

    {ОбщийМодуль.jabber.Модуль(28,4)}: Процедура или функция с указанным именем не определена (ЗапуститьПриложение)
    <<?>>ЗапуститьПриложение(sender); (Проверка: Сервер)

    Синтаксис-помошник говарит:

    Глобальный контекст (Global context)

    ЗапуститьПриложение (RunApp)

    ……

    Доступность:

    Тонкий клиент, веб-клиент, толстый клиент.

    Сервера нету 🙁

    1С:Предприятие 8.2 (8.2.13.219)

    Reply
  10. KroVladS

    Но это только пол беды сами PHP скрипты при запуске из CMD не отправляют сообшения 🙁

    Понимаю что php скрипт не ваш но может что посовеуете, по логам видно что конект прошол и сообшение отправлено.. а ничего не приходит.

    Version: Openfire 3.6.4

    2012-05-16 17:29:56
    Initializing class variables
    2012-05-16 17:29:56
    Trying to connect at server-2010:5223
    2012-05-16 17:29:58
    Connection made successfully at server-2010:5223
    2012-05-16 17:29:58
    Sending XML>>
    <?xml version=»1.0″?><stream:stream xmlns:stream=»http://etherx.jabber.org/streams» version=»1.0″ xmlns=»jabber:client» to=»orion» xml:lang=»en» xmlns:xml=»http://www.w3.org/XML/1998/namespace»>
    2012-05-16 17:29:59
    Sending XML>>
    <message type=»chat» from=»helpdesk@domen» to=»user@domen»><body>Тестовое сообщение</body></message>
    2012-05-16 17:29:59
    Sending XML>>
    </stream:stream>

    Показать

    Reply
  11. X.Leshiy

    (10) KV1s, файл с сообщенем в UTF-8 кодировке? Это обязательно.

    Reply
  12. X.Leshiy

    (9) KV1s,

    Общий модуль с настройками Сервер и Вызов сервера.

    Версия 1С 1.8.15.301 x64.

    Клиент-серверный вариант.

    У меня вот что выдает синтакс помощник:

    Глобальный контекст (Global context)

    ЗапуститьПриложение (RunApp)

    Синтаксис:

    ЗапуститьПриложение(<СтрокаКоманды>, <ТекущийКаталог>, <ДождатьсяЗавершения>, <КодВозврата>)

    Параметры:

    <СтрокаКоманды> (обязательный)

    Тип: Строка.

    Командная строка для запуска приложения либо имя файла, ассоциированного с некоторым приложением.

    <ТекущийКаталог> (необязательный)

    Тип: Строка.

    Задает текущий каталог запускаемого приложения.

    В режиме веб-клиента игнорируется.

    <ДождатьсяЗавершения> (необязательный)

    Тип: Булево.

    Истина — дожидаться завершения запущенного приложения перед продолжением работы.

    Значение по умолчанию: Ложь

    <КодВозврата> (необязательный)

    Тип: Число; Неопределено.

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

    Для получения кода возврата значение параметра ДождатьсяЗавершения должно быть установлено в Истина, запускаемое приложение должно существовать и завершить свою работу корректно.

    Описание:

    Выполняет запуск внешнего приложения либо открытие файла с использованием ассоциированного с ним приложения.

    Доступность:

    Тонкий клиент, веб-клиент, сервер, толстый клиент.

    Примечание:

    В отличие от функции КомандаСистемы запуск приложения выполняется непосредственно, минуя командный интерпретатор.

    Поведение метода зависит от используемой операционной системы и режима запуска. Используемые в реализации метода механизмы операционной системы допускают различные варианты использования. Например, в некоторых режимах метод может открывать html ссылки с помощью браузера «по умолчанию». Такие возможности не являются штатными т.к. не гарантируется их наличие во всех режимах запуска.

    Для работы метода на веб-клиенте, необходимо предварительно подключить расширение работы с файлами.

    Пример:

    // открытие файла MS Excel

    ЗапуститьПриложение(«Таблица.xls»);

    Reply
  13. KroVladS

    (11)

    Файл в UTF-8

    Reply
  14. KroVladS

    (12)

    Надо обновлять платформу????

    Reply
  15. X.Leshiy

    (14) KV1s, ну я же не знаю, что у вас там и как, опишите подробнее.

    Reply
  16. KroVladS

    (15)

    1С:Предприятие 8.2 (8.2.13.219)

    Сервер 1с

    Надо обновлять платформу!!!

    Reply
  17. KroVladS

    (10) KV1s,

    Проблема была в методе шифрования. Исправил в xmpp.class.php

    stream_socket_enable_crypto($this->stream, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
    Заменил на
    stream_socket_enable_crypto($this->stream, TRUE, STREAM_CRYPTO_METHOD_SSLv3_CLIENT);

    (9) KV1s,

    В общем модуле

    ЗапуститьПриложение(sender);
    Заменил на
    WshShell = Новый COMОбъект(«WScript.Shell»);
    WshShell.Run(sender, 0, Истина);

    и платформу обновлять не надо.

    Всё отправляет 🙂 Большое Спасибо 🙂

    Вот только $webi->connect(); медлено происходит, секунд 10.

    И ещё у Вас в статье редактор испортил строчку кода.

      ТекСтрока  = «; ТекТекст.ДобавитьСтроку(ТекСтрока);
    следует заменить на
    ТекСтрока  = «<?php»; ТекТекст.ДобавитьСтроку(ТекСтрока);
    Reply
  18. X.Leshiy

    (17) KV1s, спасибо, ошибку исправил.

    Reply
  19. X.Leshiy

    Черт, все равно не прошло «<?php», я так понимаю, автоматом редактор убирает потенциально опасные слова.

    Reply
  20. KroVladS

    (19)

    оформи тегом

    [1C-CODE] [ /CODE]
    Reply
  21. electronik

    Интересно интересно недавно столкнулся с похожей проблемой сервер намертво зависал буду пробовать

    Reply
  22. X.Leshiy

    (21) electronik, обратите внимание что в публикации редактор скушал часть строки. Правильный вариант в коментарии №17.

    Reply
  23. denek2004

    Для 1с 7.7 кто -нибудь подключал ?

    Reply
  24. X.Leshiy

    А в чем проблема?

    Принцип работы такой: формируется текстовый файл с php кодом с расширением .php, запускается с помощью интерпретатора. Чем он формируется, разницы нет.

    Reply
  25. pallid

    (2) cool.vlad4,У меня никак не срабатывает событие OnMessage, может там тоже какие то танцы с бубном, как и с отключением, не подскажете???

    Reply
  26. pallid

    А проблема падением базы решилась так:

    JS = Новый COMОбъект(«JabberCOM.JabberSession»);
    ДобавитьОбработчик JS.OnConnect, OnConnect;
    ДобавитьОбработчик JS.OnMessage, OnMessage;
    JS.Server = «jabber.ru»;
    JS.Username = логин;
    JS.Password = пароль;
    JS.Resource = «Script»;
    JS.Priority = 1;
    DoConnect = JS.DoConnect(Ложь,0); //Без присвоения падает
    
    Предупреждение(«Соединение», 5); //Надо а то база падает
    
    msg = Новый COMОбъект(«JabberCOM.JabberMsg»);
    
    Предупреждение(«Соединение», 5); //Надо а то база падает
    
    msg.MsgType = 0;
    msg.Body = «text»;
    msg.ToJID = «кому@jabber.ru»;
    
    JS.SendMessage(msg);
    DoConnect = JS.DoConnect(Истина,0); //Без этого тоже падает
    
    Предупреждение(«Выход», 5); //На всякий случай
    
    JS.DoDisconnect(Истина);
    

    Показать

    Reply
  27. masspi

    Скажите, не могли бы Вы немного подробнее описать механизм интеграции?

    Reply
  28. Mogidin

    Обзовите меня некропостером, но…

    Насколько я понимаю, чтобы сервер смог что-то записать в файлик на «\servere$AddInjabber», нужно пользователю, под которым запущен сервер, дать права на запись на диск Е. Так?

    Reply
  29. X.Leshiy

    (28) Mogidin, Да, без прав никак. Но, можно класть файлы на любую шару, не обязательно на сервер, если безопасность и все такое 🙂

    У меня запись на E$ была, ну, потому что вот так сделал, потом просто не менял.

    Никакого умысла 🙂

    Reply
  30. FlagmanGK
    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *