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.php, xml.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 не будет опубликован. Обязательные поля помечены *