Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?
- error_reporting(E_ALL & ~E_NOTICE);
- set_time_limit(0); // убираем ограничения на время исполнения, чтобы крутилось вечно
- $fullPath='/var/www/html/xmpp/'; // полный путь в файловой системе к папке с прогой
- require_once($fullPath.'include/ipworks_xmpp.php'); // подключаем файл с классом от производителя модуля
- $sleepTime=1; // время остановки в секундах после прохода вечного цикла
- $msg_file_name=$fullPath.'messages.txt'; // задаём путь к файлу-буферу, т.к. обрабатываем вывод раз в
- class MyXMPP extends IPWorks_XMPP { // создаём новый класс с наследованием методов и свойств класса IPWorks_XMPP от производителя модуля
- /*
- функции обработки событий
- для ActiveX, из которого сделан модуль для 1С, описаны тут http://cdn.nsoftware.com/help/IP9/acx/XMPP.htm#Events
- я же пользуюсь отсюда, но там всё одинаково http://cdn.nsoftware.com/help/IP9/php/XMPP.htm#Events
- */
- function fireConnectionStatus($param) {
- // событие состояния соединения, тут оно не обрабатывается, но в случае использования в продакшене в этом месте надо вызывать пересоздание соединения, если оно разорвалось
- print_r($param); // печать параметров события в стандартный вывод
- return $param; // возврат функции
- }
- function fireIQ($param) {
- /*
- событие IQ сообщений (системных), например, чтобы серверу узнать что клиент всё ещё на связи, он его периодически пингует, если клиент отвечает в пределах таймаута (в нашем случае 360 сек), то поддерживается он-лайн статус соединения, выглядит это примерно так:
- -------------------- fireIQ ---------------------------
- Array
- (
- [iq] => <iq type="get" id="362-24749" from="qip.cons23.ru" to="ipworksphp1@qip.cons23.ru/IP*Works! XMPP Agent"><ping xmlns="urn:xmpp:ping"/></iq>
- [id] => 362-24749
- [from] => qip.cons23.ru
- [iqtype] => get
- [ignore] => 0
- )
- -------------------- fireIQ end------------------------
- -------------------- firePITrail ---------------------------
- Array
- (
- [direction] => 0
- [pi] => <iq from='ipworksphp1@qip.cons23.ru/IP*Works! XMPP Agent' to='qip.cons23.ru' id='362-24749' type='result'/>
- )
- -------------------- firePITrail end------------------------
- */
- print_r($param); // печать параметров события в стандартный вывод
- return $param; // возврат функции
- }
- function firePITrail($param) {
- // событие для всех сообщений протокола, имеет два параметра: направление (0 - от клиента к серверу, 1 - от сервера клиенту, 2 - информационное) и само сообщение
- global $msg_file_name; // делаем переменную глобальной, чтобы использовать внутри функции
- if ($param['direction']==1) { // смотрим сообщения полученные с сервера
- if (preg_match('/body/si', $param['pi'])) { // смотрим сообщения, у которых есть тело (регулярка проверяет наличие тега <body>)
- preg_match("/^.+id=\"(.*?)\".*type=\"(.*?)\".*from=\"(.*?)\".*<body>(.*?)<\/body>.*<thread>(.*?)<\/thread>.+$/si", $param['pi'], $output_array);
- /* разбираем сообщение на запчасти с помощью регулярного выражения, оригинальные сообщения выглядят примерно так:
- <message to="ipworksphp1@qip.cons23.ru/IP*Works! XMPP Agent" id="YeCon-5376" type="chat" from="pestretsov.aa@qip.cons23.ru/Spark"><body>Тело сообщения</body><thread>qAh2Hi</thread><x xmlns="jabber:x:event"><offline/><composing/></x><active xmlns="http://jabber.org/protocol/chatstates"/></message>
- */
- if (count($output_array)==6 && $output_array[2]=='chat' && preg_match("/^[a-zA-Z]{1,20}\.[a-zA-Z]{2}@qip\.cons23\.ru(|\/.+)$/si", $output_array[3])) { // проверяем что сообщение запарсилось и у нас на выходе массив на 6 элементов, чтобы два раза не вставать смотрим ещё чтобы тип сообщения был chat, а отправитель укладывался в наш паттерн (имел имя пользователя как у нас в домене, домен чтобы был тоже наш)
- $mID=$output_array[1]; // ID сообщения
- $mType=$output_array[2]; // Тип сообщения
- $mFrom=$output_array[3]; // Отправитель сообщени
- $mBody=$output_array[4]; // Тело сообщения
- $mThread=$output_array[5]; // ID разговора
- $mTypes=array_flip(array("normal", "chat", "groupchat", "headline", "error")); // создаём массив строковых типов сообщений (мы там вверху в регулярке фильтруем только chat, но можно отвечать на любые) и переворачиваем массив, т.е. если на создании он у нас 4=>error, то теперь будет error=>4
- $mType=$mTypes[$mType]; // меняем наше текстовое название типа сообщения на цифровое
- $order = array("\r\n", "\n", "\r"); // т.к. в сообщениях может встречаться символ перевода строки, а я собираюсь хранить сообщение в строку, то от этих символов надо избавиться, тут задаётся массив таких символов
- $replace = '<br />'; // это на что я их буду менять, в данном случае тег перевода строки из html
- $mBody=str_replace($order, $replace, $mBody); // заменем подстроки $order на $replace
- file_put_contents($msg_file_name, $mFrom.'|||'.$mType.'|||'.$mBody.'|||'.$mID.'|||'.$mThread."\n", FILE_APPEND | LOCK_EX); // пишем строку в файл, разделитель у нас ||| так что если попадёт сообщение с такой подстрокой, то получим косяк
- }
- }
- }
- print_r($param); // печать параметров события в стандартный вывод
- return $param; // возврат функции
- }
- }
- $xmpp = new MyXMPP(); // создаём объект из класса выше
- $xmpp->setPresence(1); // параметр что мы будем показывать себя как он-лайн пользователя
- $xmpp->setTimeout(0); // ставим вечный таймаут
- $xmpp->doConfig('codepage=65001'); // кодировка UTF8
- $xmpp->doConfig('ParseHTML=true'); // эта опция нужна если мы будем отправлять HTML сообщения, то наш класс их распарсим и отправит текстовую часть как текст для совместимости
- $xmpp->setIMServer('qip.cons23.ru'); // сервер
- $xmpp->setAuthMethods('SASL/PLAIN'); // тип авторизации
- try {
- $xmpp->doConnect("IPworksphp1", "IPworksphp1"); // соединяемся с именеи и паролем
- } catch (Exception $e) {
- file_put_contents($fullPath.'send_connection.log', $e->getMessage(), FILE_APPEND | LOCK_EX); // если ошибка подключения, то пишем её в файл
- }
- while (true) { // заводим вечный цикл
- $xmpp->doEvents(); // обрабатываем события из внутренней очереди, например, отвечаем серверу на пинги, в модуле уже это встроено, поэтому на такие события не надо писать пользовательской функции
- if (is_file($msg_file_name) && filesize($msg_file_name)>12) { // смотрим существует ли наш файл-буфер исходящих сообщений
- $sendArray=file($msg_file_name); // читаем файл в массив (каждая строчка - элемент)
- unlink($msg_file_name); // удаляем наш файл-буфер
- $replace = "\r\n"; // задаём символы перевода строки для обратного преобразования
- $order = '<br />'; // задаём символы перевода строки для обратного преобразования
- foreach ($sendArray as $line) { // проходимся по каждому элементу массива сообщений
- $sendVars=explode ('|||', $line); // переводим нашу строку с разделителями обратно в массив
- $mID=$sendVars[3]; // ID сообщения
- $mType=$sendVars[1]; // Тип сообщения
- $mFrom=$sendVars[0]; // Отправитель сообщени
- $mBody=$sendVars[2]; // Тело сообщения
- $mThread=$sendVars[4]; // ID разговора
- $mBody=str_replace($order, $replace, $mBody); // заменем подстроки $order на $replace
- $xmpp->setMessageText($mBody); // задаём текст сообщения
- $xmpp->setMessageType($mType); // задаём тип сообщения
- $xmpp->setMessageThread($mThread); // задаём ID разговора
- try {
- $xmpp->doSendMessage($mFrom); // отправляем сообщение пользователю
- } catch (Exception $e) {
- file_put_contents($fullPath.'send_error.log', $e->getMessage(), FILE_APPEND | LOCK_EX); // если что-то пошло не так пишем ошибку в лог
- }
- }
- }
- sleep($sleepTime); // на завершении прохода цикла приостанавливаем выполнение на $sleepTime секунд, т.к. на полной скорости нам работать не нужно
- }
- $xmpp->doDisconnect(); // тут отключаемся, но это можно не делать, т.к. при нормальном выполнении до сюда всё равно не дойдёт, а на непойманном исключении программа просто завершится и всё равно до сюда не дойдёт
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement