<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55
global $wpdb2;
global $failure;
global $file_hist;
///// echo '<H2><b>Старт загрузки</b></H2><br>';
$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
///// echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
{ foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\
блин, код уехал…
а как кошерно вставить 1с’вский код в редакторе статей?
Мдааа… вот скажите, зачем было разукрашку выкладывать только для зарегистрированных и тремя разными файлами. Ну шо, ждем 00 часов чтобы скачать xml’ник…
ступил… ну вот, кажись все, жду комментариев и конструктивной критики
интересно, а можно с помощью этой шины сообщенйи организовать обмен между 2-я сеансами 1Ски?
Качество мультика — отвратное
(5) Элементарно, если каждому сеансу будет присвоена своя очередь, например, можно сопоставить справочник сотрудников пользователям 1С и дописать в справочник реквизитом очередь, которую надо будет опрашивать. Таким образом каждый экземпляр/сеанс будет знать откуда ему получать сообщения, плюс у него будет «адресная книга» с очередями всех остальных экземпляров. Экземпляры/сеансы должны в данном случае отличаться друг от друга по пользователям.
(6) Ютуб, шо ты хочешь, там еще кнопочка HD есть — чуть получше будет.
(7) Собственно, чтобы организовать обмен между двумя совместимыми по данным системами тебе нужно знать только откуда читать и куда писать. Ну и учесть те или иные особенности систем (типа удаления регистрации и игры с номерками в 1С).
(8) Обмен сообщениями может идти даже в рамках одного процесса, есть у ActiveMQ такой режим — транспорт внутри JVM. В приложении с большим количеством потоков позволяет обменивать данными не через общие переменные, и, как следует, избежать синхронизации. Аналогично сделано в эрланге, там это вообще основной способ взаимодействия.
(9) Более того, в рамках многопоточного процесса(ов) можно даже использовать внешнюю шину, сохраняющую сообщения в некоем постоянном хранилище — это позволит получить восстановление состояние процесса(ов) после сбоя. По крайней мере в границах транзакций шины сообщений, если кто-то успел что-то положить и сказать commit — его это уже больше не волнует, если кто-то не успел получить что-то и сказать commit — он получит это еще раз.
чтобы собрать проект в VS2008 пришлось добавить NUnit в GAC
Хорошее начинание. Можно сделать из этого конфетку.
и да, EIP рулит 🙂
было бы неплохо не пинать очередь на предмет наличия сообщений, а привязать событие прихода сообщения к какому-нибудь обработчику в 1С.
а обработчик как вызывать из ВК? прокинуть во внешнюю компоненту экземпляр обработки и дергать у нее методы? Или оформить все в виде псевдо активикса? какие еще возможны варианты?
P.S. Или поднять опрос очереди в виде отдельного сервиса, а из него при поступлении сообщений поднимать V8.Application и вызывать обработчик, передавая ему в качестве аргумента адаптер, чтобы можно было полностью контролировать транзакцию.
(12) Можно и конфетку, самое главное найти этому применение…
В планах на ближайшую неделю-другую устроить краш тест — создать по 200 тысяч элементов в номенклатуре, добавить какой-нибудь реквизит и менять его в центре и на магазине, гоня все это дело туда сюда. Ну и переписать обработку так, чтобы все билось на несколько сообщений. Заодно сделать сообщения об ошибках в виде структурированного xml.
(11) Там огрызок от юнит теста, которым я отлавливал глюк в agsXMPP.
(14) угу, прокинуть экземпляр обработки и дергать методы.
или вызывать методы глобального контекста.
(17) А как передать глобальный контекст текущего сеанса в ВК?
(18) ВК может запросить свойство AppDispatch у указателя, полученного в Init.
Это и будет «глобальный контекст».
Только это должен быть объект ВК, а не просто COM-объект.
+(19) немного ссылочек:
http://www.rsdn.ru/article/dotnet/cs1c.xml
(20) спасибо, посмотрю
А если ВК, значит никакого серверного варианта.
А если COM? GetCOMObject на сервере доступен?
(23) Ком работает, так, но не передается контекст 1С
тогда возможно стоит отказаться от идеи обработчика и вызывать HasMessages в регламентом задании
А зачем нужен контекст 1С? Вообще, стоит подобную систему организовать в качестве службы, которая при получение входящих сообщений подключалась бы к 1С и производила необходимые действия.
(26) как вариант
А чем принципиально плохо опрашивать очередь из 1С? Например, из регламентного задания.
(27) А то, что ты будешь опрашивать каждый заданный интервал времени, когда можно инициировать обработку данных только после получения сообщения.
(28) И? Опрашивать в регламентном задании раз в 5-10 минут — интервал зависит от интенсивности и размера сообщений, можно хоть раз в час.
(29) не нравится! почувствуй разницу в двух задачах: выполнить действие при приходе сообщения извне и проверять, а не случилось ли сообщение и если да — тогда что-то сделать… Допустим у меня есть в сутки 5 критичных сообщений, которые д.б. обработаны не позже чем через 5 сек после их прихода. и мне что — каждые 5 сек дергаться-проверять? вместо того, чтобы по приходу сообщения тут же выполнить то, что надо…
(30) можно узнать, что за задача требует такой реакции? вряд ли это обмен
обмен как таковой меня не интересует пока.
если сможете «нарисовать» красивую схему когда разные сеансы 1Ски, работающие в одной базе, обмениваются инфой/сообщениями. полученное сообщение может породить длинную цепочку действий. Я НЕ ХОЧУ ПРОВЕРЯТЬ ПРИШЛО ЛИ СООБЩЕНИЕ, я хочу после прихода сообщения получить «сигнал», и по наличию этого сигнала что-то сделать.
(32) Как уже выше предлагалось оформить все в в виде ВК, тем более, что судя по всему Вас вполне устроит работа в на клиентской стороне.
В метод Init ВК приезжает контекст одинэски а в SetParameter скармливается имя процедуры в глобальнике. При получении сообщения эта процедура дергается и ей скармливается аргументом сам адаптер, чтобы внутри процедуры можно было иметь полный контроль на транзакцией, ну а там в цикле точно также получаются все сообщения. В следующей версии можно попробовать реализовать.
Скиншот 1
Кеды «Престарелый гопник» экстрим эдишн
Охренеть — дайте две! 🙂
А зачем такой геморой ? Уж если применять шину данных, то пользоваться серьзным, промышленным решением, типа BizTalk.
(36) Можно и так, но я с ним не сталкивался — это первое. Особого геморроя я тут не вижу — это второе, дешево и вполне способно заменить файловый обмен, особенно с учетом того, что сообщения в файлы все равно сохраняются и повторная отправка делается на счет раз. Ну а если в середину вставить XSL трансформатор, то можно и с другими системами меняться.
Ну и наконец, с таким же интерфейсом можно сделать адаптеры к другим системам обмена сообщениями, например, к ActiveMQ — а это уже быдложабка 2 EE (я специально сделал один интерфейс для MSMQ и для XMPP, чтобы это продемонстрировать). Интеграция с BizTalk’ом вряд ли будет чем-то отличаться от вариантов приведенных в статье и в обсуждении. И опять же, не бизтолком единым, есть и другие решения — COM, XML сериализация и планы обмена дают большой простор для фантазии, например, я знаю как можно интегрировать эску с практически любым ESB (пробовал на OpenESB).
>я знаю как можно интегрировать эску с практически любым ESB (пробовал на OpenESB)
с этого момента, пожалуйста, поподробней
(37) будет время, постараюсь еще одну статейку накатать
А кто-нибудь пробовал в сети этот пример запустить? Проходят сообщения?
(39)
Я пробовал, все работает 😉
(40) А у меня всё получилось только после целого ряда дополнительных телодвижений. Большая часть была произведена возможно по своей неопытности, но пришлось даже свойства сборки менять и dll перекомпилировать. Я правда пытался связь между XP и 2003 Server наладить…
(41) Интересно, а какие компоненты MSMQ дополнительно ставили? На висту хоум басик многих вещей не поставишь.
(42) Локально на одной машине заработало так как и было. То есть на XP пришлось только прорегистрировать DLL с помощью regasm.exe.
А вот на Win2k3 Server пришлось в AssemblyInfo.cs прописать:
using System.Security;
[assembly: AllowPartiallyTrustedCallers()]
И перекомпилить — только после этого пошло…
Что касается непосредственно компонентов MSMQ, то в итоге стоят почти все доступные. 🙂
Сейчас только осталось разобраться с роутингом и прочими наворотами, чтобы сообщения проходили между хостами, которые не пересекаются во времени.
(43) Спасибо, если будет возможность и желание — поделитесь опытом, например, в виде статьи.
P.S. А я постараюсь через недельку подогнать еще одну, на этот раз на тему интеграции 1С с шиной веб-сервисов OpenESB.
(44) Да собственно на статью материала маловато. Все полезные выводы уместились в предыдущий комментарий.
А вот взгляд на интеграцию с другой точки:http://infostart.ru/blogs/1236/
Хотя для взаимодействия через план обмена предпочтительнее использовать таки обычную шину сообщений.
Вопрос, а как эта система будет работать в распределенной (через интернет) сети?
Ну, во-первых, у MSMQ есть множество разных компонентов (с TCP транспортом, с HTTP и пр.).
Во-вторых, в строке соединения с очередью можно указывать транспорт и имя узла, если не ошибаюсь, что-то такое:
DIRECT=TCP:IPAddressQueueName;
Это ж у меня все локально аля «.Private$….»
В-третьих, вон там выше есть товарищ с ником hotey, он наладил обмен между разными узлами внутри локалки.
P.S. Кроме того там есть еще такая вещь как каналыhttp://www.codeproject.com/KB/IP/msmqchannel.aspx
>Direct format names are used to reference public or private queues without accessing the directory service. Direct format names are used when performing the following operations:
* Sending messages directly to a computer.
* Sending messages to computers over the Internet.
* Sending messages across forest boundaries.
* Sending messages to any queue while operating in domain, workgroup, or offline mode.
* Reading messages while operating in domain, workgroup, or offline mode.
там же:
> DIRECT=TCP:157.18.3.1MyQueue
Но:
>Security Limitations
>Opening a remote queue for sending messages with a direct format name signals Message Queuing not to query the directory service when it opens the queue. This enables Message Queuing to send messages in workgroup and offline mode and to transmit messages across forest boundaries, but it eliminates the possibility of using some of the security functionality provided by Message Queuing for access control, authentication, and encryption. When security services performed by Message Queuing are unavailable, it is the responsibility of your application to implement the missing functionality.
Хотя если есть VPN, то наверное не страшно.
Вот вроде бы вариант с использованием HTTPS:http://technet.microsoft.com/en-us/library/cc736680(WS.10).aspx
В случае с HTTPS все сводится к разрешению подключения только доверенных клиентов и раздаче этим клиентам сертификатов. Сертификат есть, подключишься, сертификата нету:
IIS 5.0: HTTP 403.16 Forbidden: Client Certificate Untrusted or Invalid.
или что-то подобное
Ну и у сервера свой сертификат должен быть.
Поправьте меня, если я ошибаюсь.
1) MSMQ позволяет сохранять сообщения для отправки в очереди.
2) а что будет, если адресат, которому эта очередь предназначена не будет регулярно получать сообщения?
Т.е. ситуация: Имеем нерадивого подписчика обмена, который не хочет, не умеет, забывает делать обмен, в мерцающем режиме появляется в Интернете и как результат не забирает сообщения, которые ему предназначены.
Далее. Характер данных, передаваемых в обмене имеет существенно древовидную структуру, такую, что загрузка последующих сообщений без загрузки предыдущих — просто разрушит целостность дерева у клиента. Т.о. мы не можем очистить его очередь или оптимизировать его сообщения так, чтобы их количество и объем уменьшились.
Тогда мы получаем потенциальную опасность безграничного разрастания очереди для получателя обмена.
Если количество получателей будет измеряться многими сотнями, а то и тысячами, то данная схема должна предусматривать возможность защиты от пожобных ситуаций, иначе мы просто впустую сожрем место на сервере MSMQ
В качестве иллюстрации того, что при желании схему можно закрутить как угодно: при некоторой степени извращенности можно собрать кластер для бедных, в виде фоновой службы запущенной на офисных компах, которая через специальные очереди (или еще как) выгребает код скрипта или готовую библиотеку с точкой входа, а потом обрабатывает сообщения-запросы в соответствии с загруженной логикой, потихоньку отъедая избыточную вычислительную мощность у секретарши Маши и кадровички Любы.
Пнул новый скрипт/библиотеку — изменил логику обработки. Маша выключила компьютер? Не страшно, ведь осталась Люба! Правда остается еще вопрос с источником данных, в него тоже можно упереться (производительность/блокировки).