|
Номера сообщений при обмене с внешней системой через JSON | ☑ | ||
---|---|---|---|---|
0
Антиквар
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. :-)
|
|||
3
DrShad
11.10.21
✎
09:10
|
(1) +100500
|
|||
4
Kassern
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, спасибо, но как-то бы не хотелось таким путем идти. |
|||
7
Cyberhawk
11.10.21
✎
09:26
|
"Если пакет не принят, то повторяем всё заново, в итоге в новую выборку изменений кроме новых объектов попадут и все объекты из предыдущего пакета, только в таблице регистрации изменений им уже присвоится следующий новый номер сообщения"
Нет, ВыбратьИзменения присвоит номер только тем записям у которых номер = null |
|||
8
Kassern
11.10.21
✎
09:28
|
(6) Создай тогда свою систему через регистр сведений, со своими номерами сообщений и регистрацией. Перед выгрузкой меняй номер сообщения (какая нить константа) и делай запрос к регистру. После выгрузки очищай это добро. Будет свой лисапед. Можно и еще круче, создай внешнюю очередь через какого нить RabbitMQ, внешней компонентой с ним любайся.
|
|||
9
Антиквар
11.10.21
✎
09:34
|
(7) А как тогда повторно отправить потерянный пакет? т.е. повторно выбрать эти изменения
|
|||
10
Garykom
гуру
11.10.21
✎
09:36
|
(0) Эээ вставлять уиды пакетов-сообщений или объектов
И да json вам не xml Не принято все в один json пихать, тут лучше отдельные маленькие json'чики на каждую сущность )) |
|||
11
Kassern
11.10.21
✎
09:36
|
(9) Можешь запросом по номеру сообщения получить.
|
|||
12
Garykom
гуру
11.10.21
✎
09:38
|
(0) Надеюсь понимаешь что номера пакетов все увеличивающиеся нужны только при накопительных-кумулятивных
Чтоб даже если что пропустили то без подтверждения в следующем снова придет И вышестоящий номер подтверждает-закрывает все ниже |
|||
13
Kassern
11.10.21
✎
09:39
|
(9) или делай в транзакции, вот как 1с советует когда данные большие:
ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.ОткрытьФайл(ИмяФайла); ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); ЧтениеСообщения.НачатьЧтение(ЧтениеXML); НачатьТранзакцию(); Счетчик = 0; Пока ВозможностьЧтенияДанных(ЧтениеXML) Цикл Данные = ПрочитатьXML(ЧтениеXML); Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель; Данные.ОбменДанными.Загрузка = Истина; Данные.Записать(); Счетчик = Счетчик + 1; Если Счетчик % 1000 = 0 Тогда ЗафиксироватьТранзакцию(); НачатьТранзакцию(); КонецЕсли; КонецЦикла; ЗафиксироватьТранзакцию(); ЧтениеСообщения.ЗакончитьЧтение(); ЧтениеXML.Закрыть(); |
|||
14
Kassern
11.10.21
✎
09:39
|
||||
15
Антиквар
11.10.21
✎
09:40
|
(8) свою систему запилить всегда можно, но как правило в итоге оказывается, что много всего нужно учитывать и в самом деле получается изобретение велосипеда. Хотелось бы к стандартным возможностям привязаться. Тем более с блокировками данных там реализовано. Хотя может это как раз таки будет тормозить и лучше своё писать)
"Можно и еще круче, создай внешнюю очередь через какого нить RabbitMQ" - так и предполагается, но отправление пакета брокеру не значит подтверждение его загрузки во внешней системе. Подтверждение также придет из брокера в 1С через какое-то время. Вот и надо будет это в 1С обработать |
|||
16
Garykom
гуру
11.10.21
✎
09:44
|
(15) >RabbitMQ" - так и предполагается, но отправление пакета брокеру не значит подтверждение его загрузки во внешней системе. Подтверждение также придет из брокера в 1С через какое-то время. Вот и надо будет это в 1С обработать
эээ вы фигню хотите отвечайте только за себя а внешняя система будет отвечать за себя т.е. возвращать ответы только об ошибках загрузки и вы их обрабатывайте раббит и прочее они гарантируют доставку в конечную если конечная теряет пакеты то это упс |
|||
17
Антиквар
11.10.21
✎
09:51
|
(16) "раббит и прочее они гарантируют доставку в конечную" - я с этим пока не работал, и для меня непривычно, что какая-то прослойка (пусть даже мегакрутая) может что-то гарантировать) Хотелось бы получать подтверждения.
|
|||
18
Kassern
11.10.21
✎
09:51
|
На практике проблема возникает в основном на загрузке данных. Выгрузка может закосячиться, если только меняли протокол обмена, либо вырубили сервер в момент выгрузки. В первом случае множество отладок перед продакшеном, а во втором - УПС. Да это не 100% гарантия, но даже, если и произойдет сбой и синий экран смерти на серваке, то можно же логировать обмены, если нет информации о завершении обмена, то можно заново отправить выгрузку с этим номером сообщения. Только после успешной выгрузки надо удалять изменения с этим номером.
|
|||
19
Антиквар
11.10.21
✎
09:53
|
(12) "Чтоб даже если что пропустили то без подтверждения в следующем снова придет" - я так и хочу реализовать. Но если следующая выборка изменений не включает в себя то что уже ушло, но не удалено из регистрации, то нужно что-то своё писать, как в посте (11). Стандартных методов нет как я понимаю.
|
|||
20
Kassern
11.10.21
✎
09:54
|
Сколько времени занимает полная выгрузка данных?
|
|||
21
Антиквар
11.10.21
✎
09:59
|
(18) "можно заново отправить выгрузку с этим номером сообщения"
Т.е. можно сделать запрос к таблице регистрации изменений, указав номер сообщения? Просто не изучал этот вопрос. Знаю что у каждого объекта метаданных есть таблица изменений, т.е. можно сделать запрос, выборку из например Справочник.Контрагенты.Изменения Но это все объекты перечислять и есть ли тут фильтр по номеру сообщения... |
|||
22
Антиквар
11.10.21
✎
10:00
|
(20) пока не знаю. Предлагаешь раз в день полную выгрузку делать и не заморачиваться с подтверждением загрузки? )
|
|||
23
Kassern
11.10.21
✎
10:02
|
(22) на некоторых проектах так и было реализовано. Полная выгрузка не занимала там дофига времени. Если и происходил сбой то, выполнялась полная выгрузка.
(21) В запросе есть такой значок "отображать таблицы изменений", нажимая на него, появляются данные таблицы. Там можно по узлу и номеру сообщения получить нужные данные. |
|||
24
Garykom
гуру
11.10.21
✎
10:04
|
(19) А оно точно надо?
Раббит и прочее подразумевает очередь! Т.е. в порядке очереди все работает Если одно сообщение (при отправке или отгрузке) упало то обычно на этом все останавливается и ждем вмешательства ответственных |
|||
25
Garykom
гуру
11.10.21
✎
10:05
|
(24)+ Последующие сообщения после упавшего не отсылаются и не загружаются
Ибо предполагают что нельзя последовательность нарушать сообщений |
|||
26
Антиквар
11.10.21
✎
10:45
|
(25) Я с брокерами ранее не работал, мне спокойнее самому отработать подтверждение загрузки. Но тут я возможно не прав в силу неопытности в данном вопросе
|
|||
27
Garykom
гуру
11.10.21
✎
11:06
|
(26) это просто иная методология
в случае обмена через RPC (http и веб-сервисы или com-соединение) ты же не будешь проверять что оно успешно записалось путем чтения и проверки что совпадает да? суть та же отправил пакет в очередь - и если не прилетела ошибка то пофиг, далее дело брокера и конечной системы а с учетом что на другом конце может быть несколько разных систем хотя отправляет одна смысл в подтверждениях теряется очереди можно настроить что одна конфа 1С отправляет, а получают пакеты две и более других конф 1С или иных учетных систем не надо в каждую отдельно и свои отправлять, пакеты универсальные и клонируются в каждую систему и там или грузятся если нужны или игнорируются |
|||
28
Kassern
11.10.21
✎
11:12
|
(27) здесь имелось в виду подтверждение, что брокер получил от тебя данные. А не то что конечный получатель их получил. В общем, можно в транзакции отправлять данные в брокер, если все успешно, то очищать данные по номеру, если нет, то произойдет откат транзакции и по идее следующая выгрузка заново отправит, то что не ушло.
|
|||
29
Kassern
11.10.21
✎
11:16
|
(27) простой пример, у тебя списали товар на складе, провели соответствующий документ. 1с по таймауту попыталась отправить данные о списании в брокер, но в момент выгрузки кто-то вырубил агент сервера 1с. Что тогда? В вашем случае, пофиг на этот пакет, отправим следующий. А ТС надо, чтобы при запуске службы следующая выгрузка отправила пакет с списанием, чтобы обновить остатки на сайте к примеру.
|
|||
30
Garykom
гуру
11.10.21
✎
11:20
|
(28) (29) да для этого Справочник или РС в 1С надо, где хранить до того как брокеру передали
|
|||
31
Cyberhawk
11.10.21
✎
17:34
|
(9) Ну в результат (выборку) ВыбратьИзменения все подряд попадет, включая и старые (с уже заполненным номером сообщения)
|
|||
32
Антиквар
12.10.21
✎
15:00
|
(31) Ааа, ну это другое дело. То что не поменяет номер сообщения - это не страшно, главное чтоб в выборку попало для повторной отправки.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |