понедельник, 13 мая 2013 г.

Интеграция 1С Предприятия и 1С Битрикс: про то, как мы добавили возможность передачи архива по FTP


Работая над одним из проектов, я столкнулась с тем, что когда архив с данными от 1С больше 1,5Г - обмен проходит нестабильно - рвался именно на этапе передачи файла (иногда рвался, а иногда - нет). Возможно, это общая проблема, а возможно – на конкретном сервере, а сервер там солидный. Заказчик же хотел иметь возможность делать полную выгрузку каталога, полная выгрузка представляла собой архив, объемом около 6Г.

Как известно, на третьем шаге стандартного протокола обмена 1С Предприятие по частям посылает Битриксу архив с файлами обмена в виде POST (я рассматриваю наш частный случай – объемный архив).

Я предложила 1С Программисту переписать механизм импорта каталога товаров на его и на моей стороне так, чтобы на 3м шаге обмена 1С Предприятие выкладывало архив на сервер по фтп и просто сообщало сайту об этом. Посовещавшись, решили не заменять способ передачи архива от 1С на сайт, а сделать возможность передавать его как стандартно через http в виде POST, так и посредством ftp. Наш видоизмененный протокол обмена между 1С Предприятием и 1С Битрикс выглядит следующим образом:

Шаг 1 и 2 – такие же, как в стандартном протоколе обмена
Шаг 3: 

Вариант 1:
http://<сайт>/bitrix/admin/1c_exchange.php?type=catalog&mode=file&filename=<имя файла>&method=http
1С посылает запрос и загружает на сервер файлы обмена в формате CommerceML 2, посылая содержимое файла или его части в виде POST. 

Вариант 2:
1C заливает сайт по ftp, а затем посылает сайту запрос:
http://<сайт>/bitrix/admin/1c_exchange.php?type=catalog&mode=file&filename=<имя файла>&method=ftp
(тут нужно учесть возможность того, что если 1С не успеет залить архив на сервер за время жизни сессии, то Битрикс уже может разовтаризовать 1С, и тогда перед этим запросом нужно снова авторизоваться, но у нас за время жизни сессии все по ftp залиться успевало, и не стали пока эту возможность учитывать)

В случае успешной записи файла 1С-Битрикс выдает "success".

Шаг 4 – такой же, как в стандартном протоколе.

Таким образом, мы видоизменили только 3й шаг протокола обмена – остальные шаги остались стандартными.

Для того, чтобы реализовать эти изменения на стороне сайта, я сделала в ранее уже кастомизированном компоненте импорта (но конкретно на этом участке его код совпадал со стандартным компонентом) следующее:

В блоке 

if(($_GET["mode"] == "file") && $ABS_FILE_NAME) {}

Сразу после коммента //And save it the file

Заменила условие 

if($DATA_LEN > 0) 
на 
if($DATA_LEN > 0 || $_GET["method"]='ftp')
И все – после этого компонент успешно принимал архив как загруженный кусочками в POST, так и залитый целиком на ftp (при условии, что 1С присылала соответствующий маркер). Возможно, что при этом не все возможные ошибки вылавливаются, но тогда в любом случае возникает ошибка при попытке скрипта распаковать архив, поэтому углубляться не стала.

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

В итоге проблема заливки выгрузки объемом более 1,5Г была решена.

1 комментарий:

Юрий комментирует...

Идея мне понравилось.
В своих проектах я поступаю несколько иначе:
разделяю отправку картинок и структуры каталога, т.е. картинки отправляются с помощью 1С на сервер с помощью FTP (архивом), а потом уже отправляется CML без всяких картинок, работает очень стабильно.

Стоит еще отметить:
1) В CML вырезается тег (т.е. инфоблок картинками не заполняется)
2) На сайте картинки подхватываются либо по артикулу либо по внешнему коду (как удобней именовать изображения)
3) Распаковка отправленного архива происходит средствами SSH по крон (если есть архив - распаковка с заменой).