Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Номера сообщений при обмене с внешней системой через JSON

Номера сообщений при обмене с внешней системой через JSON
Я
   Антиквар
 
11.10.21 - 08:54
Всем привет!
Требуется реализовать обмен с внешней системой по формату JSON. Причем требуется получать подтверждение загрузки пакета от этой внешней системы, следовательно придется вести учет номеров отправленных пакетов.
Если бы формат был XML, то всё понятно:
1. СообщениеXML.НачатьЗапись() – сообщению присваивается номер (на 1 больше последнего отправленного), ставится блокировка на изменение данных узла.
2. ПланыОбмена.ВыбратьИзменения(Узел, Номер) – присвоенный сообщению номер пишется в таблицу регистрации изменений по выбранным объектам.
3. СообщениеXML.ЗакончитьЗапись() – в план обмена для выбранного узла записывается номер отправленного сообщения и снимается блокировка для узла.

С форматом JSON у нас нет методов НачатьЗапись() и ЗакончитьЗапись(), следовательно нумерацию сообщений нужно вести самим. Также нужно самим позаботиться о блокировке данных.
Что касается нумерации, то вижу это так:
Перед вызовом ВыбратьИзменения() мы обращаемся к плану обмена к записи с выбранным узлом, читаем номер отправленного, увеличиваем на единицу, и полученный новый номер передаем в ВыбратьИзменения().
Таким образом в таблицу регистрации изменений по всем выгружаемым объектам проставится нужный новый номер сообщения.
После чего мы сами должны сразу прописать в план обмена для данного узла новый номер отправленного пакета.
Когда получим подтверждение от внешней системы об удачной загрузке пакета, делаем:
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Номер)
Если пакет не принят, то повторяем всё заново, в итоге в новую выборку изменений кроме новых объектов попадут и все объекты из предыдущего пакета, только в таблице регистрации изменений им уже присвоится следующий новый номер сообщения.

Просьба подсказать, всё ли правильно я понял, или в случае JSON есть какой-то другой путь. Может более удобный? Проблема в учете подтверждения загрузки, и тут видимо без номеров пакетов не обойтись.

И вопрос у меня про блокировку, как лучше её организовать. Я не совсем понимаю, какая блокировка ставится при СообщениеXML.НачатьЗапись(). Блокируется только запись плана обмена, соответствующая нашему узлу, либо же блокируются и все данные (Справочники, Документы,…), изменения которых регистрируются для данного узла обмена?
   ДенисЧ
 
1 - 11.10.21 - 08:56
Чем жисон в этом случае отличается от хамээля?
   Галахад
 
2 - 11.10.21 - 09:06
(0) Выгружай в XML и конвертируй в JSON. :-)
   DrShad
 
3 - 11.10.21 - 09:10
(1) +100500
   Kassern
 
4 - 11.10.21 - 09:12
(0) ну так начинай запись xml, чтобы получить изменения, а дальше все в json запиши. Только зачем такие велосипеды хз. Сколько секунд выиграет принимающая/отдающая сторона, если формат будет json вместо xml?)
   Антиквар
 
5 - 11.10.21 - 09:15
(1) Я выше написал чем отличается на мой взгляд. Тем, что стандартными методами обмена можно пользоваться только создавая сообщение формата XML. Поскольку только НачатьЗапись() и ЗакончитьЗапись() управляют блокировкой и автоматически увеличивают номер сообщения. Почему и спрашиваю, может для JSON в 1С тоже что-то есть, а если нет, то правильно ли я описал как нужно делать.
   Антиквар
 
6 - 11.10.21 - 09:19
(4) Формат обсуждать нет смысла, система работает только с JSON. Причем файл не создается, JSON в строку.
За вариант применять стандартные НачатьЗапись() и ЗакончитьЗапись() , а между ними делать свой JSON, спасибо, но как-то бы не хотелось таким путем идти.
   Cyberhawk
 
7 - 11.10.21 - 09:26
"Если пакет не принят, то повторяем всё заново, в итоге в новую выборку изменений кроме новых объектов попадут и все объекты из предыдущего пакета, только в таблице регистрации изменений им уже присвоится следующий новый номер сообщения"
Нет, ВыбратьИзменения присвоит номер только тем записям у которых номер = null
   Kassern
 
8 - 11.10.21 - 09:28
(6) Создай тогда свою систему через регистр сведений, со своими номерами сообщений и регистрацией. Перед выгрузкой меняй номер сообщения (какая нить константа) и делай запрос к регистру. После выгрузки очищай это добро. Будет свой лисапед. Можно и еще круче, создай внешнюю очередь через какого нить RabbitMQ, внешней компонентой с ним любайся.
   Антиквар
 
9 - 11.10.21 - 09:34
(7) А как тогда повторно отправить потерянный пакет? т.е. повторно выбрать эти изменения
   Garykom
 
10 - 11.10.21 - 09:36
(0) Эээ вставлять уиды пакетов-сообщений или объектов

И да json вам не xml
Не принято все в один json пихать, тут лучше отдельные маленькие json'чики на каждую сущность ))
   Kassern
 
11 - 11.10.21 - 09:36
(9) Можешь запросом по номеру сообщения получить.
   Garykom
 
12 - 11.10.21 - 09:38
(0) Надеюсь понимаешь что номера пакетов все увеличивающиеся нужны только при накопительных-кумулятивных
Чтоб даже если что пропустили то без подтверждения в следующем снова придет
И вышестоящий номер подтверждает-закрывает все ниже
   Kassern
 
13 - 11.10.21 - 09:39
(9) или делай в транзакции, вот как 1с советует когда данные большие:
ЧтениеXML = Новый ЧтениеXML; 
ЧтениеXML.ОткрытьФайл(ИмяФайла); 

ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); 
ЧтениеСообщения.НачатьЧтение(ЧтениеXML); 

НачатьТранзакцию(); 

Счетчик = 0; 
Пока ВозможностьЧтенияДанных(ЧтениеXML) Цикл 
   
   Данные = ПрочитатьXML(ЧтениеXML); 
   Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель; 
   Данные.ОбменДанными.Загрузка = Истина; 
   Данные.Записать(); 
   
   Счетчик = Счетчик + 1;
   Если Счетчик % 1000 = 0 Тогда 
      ЗафиксироватьТранзакцию(); 
      НачатьТранзакцию(); 
   КонецЕсли; 

КонецЦикла; 

ЗафиксироватьТранзакцию(); 

ЧтениеСообщения.ЗакончитьЧтение();
ЧтениеXML.Закрыть();
   Kassern
 
14 - 11.10.21 - 09:39
   Антиквар
 
15 - 11.10.21 - 09:40
(8) свою систему запилить всегда можно, но как правило в итоге оказывается, что много всего нужно учитывать и в самом деле получается изобретение велосипеда. Хотелось бы к стандартным возможностям привязаться. Тем более с блокировками данных там реализовано. Хотя может это как раз таки будет тормозить и лучше своё писать)
"Можно и еще круче, создай внешнюю очередь через какого нить RabbitMQ" - так и предполагается, но отправление пакета брокеру не значит подтверждение его загрузки во внешней системе. Подтверждение также придет из брокера в 1С через какое-то время. Вот и надо будет это в 1С обработать
   Garykom
 
16 - 11.10.21 - 09:44
(15) >RabbitMQ" - так и предполагается, но отправление пакета брокеру не значит подтверждение его загрузки во внешней системе. Подтверждение также придет из брокера в 1С через какое-то время. Вот и надо будет это в 1С обработать

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

раббит и прочее они гарантируют доставку в конечную
если конечная теряет пакеты то это упс
   Антиквар
 
17 - 11.10.21 - 09:51
(16) "раббит и прочее они гарантируют доставку в конечную" - я с этим пока не работал, и для меня непривычно, что какая-то прослойка (пусть даже мегакрутая) может что-то гарантировать) Хотелось бы получать подтверждения.
   Kassern
 
18 - 11.10.21 - 09:51
На практике проблема возникает в основном на загрузке данных. Выгрузка может закосячиться, если только меняли протокол обмена, либо вырубили сервер в момент выгрузки. В первом случае множество отладок перед продакшеном, а во втором - УПС. Да это не 100% гарантия, но даже, если и произойдет сбой и синий экран смерти на серваке, то можно же логировать обмены, если нет информации о завершении обмена, то можно заново отправить выгрузку с этим номером сообщения. Только после успешной выгрузки надо удалять изменения с этим номером.
   Антиквар
 
19 - 11.10.21 - 09:53
(12) "Чтоб даже если что пропустили то без подтверждения в следующем снова придет" - я так и хочу реализовать. Но если следующая выборка изменений не включает в себя то что уже ушло, но не удалено из регистрации, то нужно что-то своё писать, как в посте (11). Стандартных методов нет как я понимаю.
   Kassern
 
20 - 11.10.21 - 09:54
Сколько времени занимает полная выгрузка данных?
   Антиквар
 
21 - 11.10.21 - 09:59
(18) "можно заново отправить выгрузку с этим номером сообщения"
Т.е. можно сделать запрос к таблице регистрации изменений, указав номер сообщения?
Просто не изучал этот вопрос. Знаю что у каждого объекта метаданных есть таблица изменений, т.е. можно сделать запрос, выборку из например Справочник.Контрагенты.Изменения
Но это все объекты перечислять и есть ли тут фильтр по номеру сообщения...
   Антиквар
 
22 - 11.10.21 - 10:00
(20) пока не знаю. Предлагаешь раз в день полную выгрузку делать и не заморачиваться с подтверждением загрузки? )
   Kassern
 
23 - 11.10.21 - 10:02
(22) на некоторых проектах так и было реализовано. Полная выгрузка не занимала там дофига времени. Если и происходил сбой то, выполнялась полная выгрузка.
(21) В запросе есть такой значок "отображать таблицы изменений", нажимая на него, появляются данные таблицы. Там можно по узлу и номеру сообщения получить нужные данные.
   Garykom
 
24 - 11.10.21 - 10:04
(19) А оно точно надо?
Раббит и прочее подразумевает очередь! Т.е. в порядке очереди все работает
Если одно сообщение (при отправке или отгрузке) упало то обычно на этом все останавливается и ждем вмешательства ответственных
   Garykom
 
25 - 11.10.21 - 10:05
(24)+ Последующие сообщения после упавшего не отсылаются и не загружаются
Ибо предполагают что нельзя последовательность нарушать сообщений
   Антиквар
 
26 - 11.10.21 - 10:45
(25) Я с брокерами ранее не работал, мне спокойнее самому отработать подтверждение загрузки. Но тут я  возможно не прав в силу неопытности в данном вопросе
   Garykom
 
27 - 11.10.21 - 11:06
(26) это просто иная методология

в случае обмена через RPC (http и веб-сервисы или com-соединение) ты же не будешь проверять что оно успешно записалось путем чтения и проверки что совпадает да?
суть та же

отправил пакет в очередь - и если не прилетела ошибка то пофиг, далее дело брокера и конечной системы
а с учетом что на другом конце может быть несколько разных систем хотя отправляет одна смысл в подтверждениях теряется

очереди можно настроить что одна конфа 1С отправляет, а получают пакеты две и более других конф 1С или иных учетных систем
не надо в каждую отдельно и свои отправлять, пакеты универсальные и клонируются в каждую систему и там или грузятся если нужны или игнорируются
   Kassern
 
28 - 11.10.21 - 11:12
(27) здесь имелось в виду подтверждение, что брокер получил от тебя данные. А не то что конечный получатель их получил. В общем, можно в транзакции отправлять данные в брокер, если все успешно, то очищать данные по номеру, если нет, то произойдет откат транзакции и по идее следующая выгрузка заново отправит, то что не ушло.
   Kassern
 
29 - 11.10.21 - 11:16
(27) простой пример, у тебя списали товар на складе, провели соответствующий документ. 1с по таймауту попыталась отправить данные о списании в брокер, но в момент выгрузки кто-то вырубил агент сервера 1с. Что тогда? В вашем случае, пофиг на этот пакет, отправим следующий. А ТС надо, чтобы при запуске службы следующая выгрузка отправила пакет с списанием, чтобы обновить остатки на сайте к примеру.
   Garykom
 
30 - 11.10.21 - 11:20
(28) (29) да для этого Справочник или РС в 1С надо, где хранить до того как брокеру передали
 
 
   Cyberhawk
 
31 - 11.10.21 - 17:34
(9) Ну в результат (выборку) ВыбратьИзменения все подряд попадет, включая и старые (с уже заполненным номером сообщения)
   Антиквар
 
32 - 12.10.21 - 15:00
(31) Ааа, ну это другое дело. То что не поменяет номер сообщения - это не страшно, главное чтоб в выборку попало для повторной отправки.


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.