Подключение к ExtSdk2 через NativeAPI - Сценарии ExtSdk2 — различия между версиями

Материал из razgovorov.ru
Перейти к: навигация, поиск
 
(не показаны 2 промежуточные версии этого же участника)
Строка 26: Строка 26:
 
'''Шаг 5.''' Вызов методов компоненты:
 
'''Шаг 5.''' Вызов методов компоненты:
 
<syntaxhighlight lang="json">
 
<syntaxhighlight lang="json">
       Результат = МояКомпонента.TestHelloWorld();
+
       Результат = МояКомпонента.ReadAllXml();
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Строка 39: Строка 39:
 
         МояКомпонента = Новый("AddIn.МойМакетAddIn.AddInNativeExtension");
 
         МояКомпонента = Новый("AddIn.МойМакетAddIn.AddInNativeExtension");
  
Результат = МояКомпонента.TestHelloWorld();
+
Результат = МояКомпонента.ReadAllXml();
 
 
 
КонецПроцедуры
 
КонецПроцедуры
Строка 47: Строка 47:
 
Решить:
 
Решить:
  
1. NativeAPI сама стучится в плагин и потом ждать результат через события
+
NativeAPI сама стучится в плагин и потом ждать результат через события
 
В момент подключения, NativeAPI устанавливает соединение с СБИС3 Плагин, по этому до отправки первой команды нужно убедиться, что данное подключение установлено дождавшись событие "connected" (type=Event, data.eventName=connected).
 
В момент подключения, NativeAPI устанавливает соединение с СБИС3 Плагин, по этому до отправки первой команды нужно убедиться, что данное подключение установлено дождавшись событие "connected" (type=Event, data.eventName=connected).
 
. Подробнее см. в разделе [[#Получение и обработка событий | Получение и обработка событий]].  
 
. Подробнее см. в разделе [[#Получение и обработка событий | Получение и обработка событий]].  
 
2. Метод Connect которым будем подключаться и получать результаты обратно
 
Вызов метода Connect() или Connect("Путь до коннектора") если плагин установлен не по стандартному пути.
 
  
 
ExtSdk2 является расширением (модулем) СБИС3 Плагин. При обращении к модулю плагина требуется указывать идентификатор модуля. Получить идентификатор ExtSdk2 можно при помощи команды МояКомпонента.[[GetModule_-_NativeAPI|GetModule]].
 
ExtSdk2 является расширением (модулем) СБИС3 Плагин. При обращении к модулю плагина требуется указывать идентификатор модуля. Получить идентификатор ExtSdk2 можно при помощи команды МояКомпонента.[[GetModule_-_NativeAPI|GetModule]].
Строка 75: Строка 72:
  
 
[[Виды_событий_от_плагина_-_Сценарии_ExtSdk2|Более подробно о событиях]]
 
[[Виды_событий_от_плагина_-_Сценарии_ExtSdk2|Более подробно о событиях]]
 
Рекомендуем ознакомиться с примером реализации подключения к ExtSdk2, аутентификации и вызова одного метода на python. Данный пример не следует использовать как образец. Приведен только для понимания работы с модулем.
 
 
<syntaxhighlight lang="json">
 
 
import win32com.client
 
import json
 
import uuid
 
 
"""Шаг 1. Подключение к СБИС3.Плагин"""
 
 
ole = win32com.client.Dispatch("Tensor.SbisPluginClientCOM")  # Получаем COM объект
 
 
# При получении COM объекта плагин генерирует событие типа 'Event' c eventName=connected,
 
# поэтому если среди полученных ответов от ReadAllObject() есть событие стаким eventName, то вам удалось подключиться
 
# к плагину, иначе стоит сделать таймаут 100 - 500мс и повторить вызов ReadAllObject().Пример цикла.
 
 
# состояние подключения = False
 
connect = False
 
while not connect:
 
    events = json.loads(ole.ReadAllObject())  # получаем события от плагина и преобразуем в массив json объектов
 
    # в цикле проходим по каждому событию и ищем нужное с eventName=connected
 
    for event in events:
 
        if event['type'] == 'Event' and event['data']['eventName'] == 'connected':
 
            # если нужное событие пришло, то меняем состояние подключения на true и выходим из цикла
 
            connect = True
 
            break
 
 
    # если ожидаемое событие не найдено, то делаем таймаут в 300мс
 
    ole.Sleep(300)
 
 
# После подключения к плагину вы можете подключаться к ExtSdk2 и звать методы данного модуля
 
 
# Получаем uuid модуля ExtSdk2 через ole.GetModule. Если uuid получен, значит подключение к ExtSdk2 успешно и можно совершать запросы в модуль.
 
guid_module = ole.GetModule("ExtSdk2")  # Получаем uuid модуля ExtSdk2
 
 
"""Шаг 2. Пример аутентификации по логину и паролю"""
 
 
query_id = str(uuid.uuid4())  # генерируем идентификатор запроса (UUID) по которому будем ожидать ответ
 
module_method = "ExtSdk2.AuthByPassword"  # метод, который хотим позвать
 
parameters_module_method = json.dumps({"Login": "Ivanov", "Password": "Ivanov123"},
 
                                      ensure_ascii=True)  # формируем параметры метода ExtSdk2.AuthByPassword
 
host = "online.sbis.ru"  # хост, на который хотим пойти online.sbis.ru.
 
 
# Вызов метода аутентификации без авторизаии, чтобы получить идентификатор сессии
 
ole.CallMethodWithoutAuth(query_id, guid_module, module_method, parameters_module_method, host)
 
 
# Ожидаем ответ через ReadAllObject в цикле по query_id
 
session_id = ""  # Переменная для сохранения идентификатора сессии для вызов методов ExtSdk2 с пройденной аутентификацией
 
while not session_id:
 
 
    events = json.loads(ole.ReadAllObject())  # получаем события от плагина и преобразуем в массив json объектов
 
 
    # в цикле проходим по каждому событию и ищем нужное с ожидаемым query_id
 
    for event in events:
 
        if event['type'] == 'Message' and event['queryID'] == query_id:
 
            # если нужное событие пришло, то записываем идентификатор сессии в переменную
 
            session_id = event['data']['Result']
 
            break
 
 
    # если ожидаемое событие не найдено, то делаем таймаут в 300мс
 
    ole.Sleep(300)
 
 
"""Шаг 3. Пример вызова метода с пройденной аутентификацией"""
 
query_id = str(uuid.uuid4())  # генерируем идентификатор запроса (UUID) по которому будем ожидать ответ
 
module_method = "ExtSdk2.ReadTasksList"  # метод, который хотим позвать
 
# filter_task =  # сформируем пустой фильтр для ExtSdk2.ReadTasksList
 
parameters_module_method = json.dumps({"Filter": {
 
    "Навигация": {
 
        "РазмерСтраницы": "15",
 
        "Страница": "0"
 
    }
 
}},
 
    ensure_ascii=True)  # формируем параметры метода ExtSdk2.ReadTasksList.
 
 
# Вызов метода ExtSdk2.ReadTasksList с пройденной аутентификацией
 
ole.CallMethod(query_id, guid_module, module_method, parameters_module_method, session_id)
 
 
# Ожидаем ответ через ReadAllObject в цикле по query_id
 
result = {}  # Переменная для сохранения результата ExtSdk2.ReadTasksList
 
result_checked = False
 
while not result_checked:
 
 
    events = json.loads(ole.ReadAllObject())  # получаем события от плагина и преобразуем в массив json объектов
 
 
    # в цикле проходим по каждому событию и ищем нужное с ожидаемым query_id
 
    for event in events:
 
        if event['type'] == 'Message' and event['queryID'] == query_id:
 
            # если нужное событие пришло, то записываем результат в нужную переменную
 
            result = event['data']['Result']
 
            result_checked = True
 
            break
 
 
    # если ожидаемое событие не найдено, то делаем таймаут в 300мс
 
    ole.Sleep(300)
 
 
"""Шаг 4. Пример вызова методов с несколькими параметрами на примере CallSabyApi"""
 
query_id = str(uuid.uuid4())  # генерируем идентификатор запроса (UUID) по которому будем ожидать ответ
 
module_method = "ExtSdk2.CallSabyApi"  # метод, который хотим позвать
 
parameters_module_method = json.dumps({
 
    "Method": "СБИС.ПрочитатьДокумент",
 
    "Params": {
 
        "Идентификатор": "f2a7c885-269a-44e4-8781-cb928df94163",
 
        "ДопПоля": "ДополнительныеПоля"
 
    }},
 
    ensure_ascii=True)  # формируем параметры метода ExtSdk2.CallSabyApi.
 
 
# Вызов метода ExtSdk2.CallSabyApi с пройденной аутентификацией
 
ole.CallMethod(query_id, guid_module, module_method, parameters_module_method, session_id)
 
 
# Ожидаем ответ через ReadAllObject в цикле по query_id
 
result = {}  # Переменная для сохранения результата ExtSdk2.CallSabyApi
 
result_checked = False
 
while not result_checked:
 
 
    events = json.loads(ole.ReadAllObject())  # получаем события от плагина и преобразуем в массив json объектов
 
 
    # в цикле проходим по каждому событию и ищем нужное с ожидаемым query_id
 
    for event in events:
 
        if event['type'] == 'Message' and event['queryID'] == query_id:
 
            # если нужное событие пришло, то записываем результат в нужную переменную
 
            result = event['data']['Result']
 
            result_checked = True
 
            break
 
 
    # если ожидаемое событие не найдено, то делаем таймаут в 300мс
 
    ole.Sleep(300)
 
 
</syntaxhighlight>
 
  
 
[[Категория:Сценарии ExtSdk2]]
 
[[Категория:Сценарии ExtSdk2]]

Текущая версия на 12:08, 29 марта 2023

Подключение NativeAPI к 1С

NativeAPI - технология, которая позволяет создавать внешние компоненты для 1С, что рассширяет возможности данной программы. Ее главное преимущество - это работа не только на Windows системах, в отличие от COM объекта, который не может работать в Linux. Подробнее про NativeAPI можно почитать на сайте its.1c.ru

Для подключения расширения NativeAPI к 1С необходимы следующие шаги:

Шаг 1. Иметь архив с расширением .zip, который будет содержать нужную версию dll и файл MANIFEST.XML( Например NativeAPI_Connector.zip )

Шаг 2. Добавить общий макет с типом ДвоичныеДанные и назвать его, например МойМакет. Далее загрузить в макет файлы из подготовленного архива с внешней компонентой с помощью команды карточки макета Загрузить из файла - NativeAPI_Connector.zip.

Шаг 3. Установить внешнюю компоненту:

       УстановитьВнешнююКомпоненту("ОбщийМакет.МойМакет");

МойМакет - название макета, в который загружена компонента

Шаг 4. Подключение внешней компоненты происходит через последовательные команды:

       ПодключитьВнешнююКомпоненту("ОбщийМакет.МойМакет", "МойМакетAddIn", ТипВнешнейКомпоненты.Native); 
       МояКомпонента = Новый("AddIn.МойМакетAddIn.AddInNativeExtension");

Текст МойМакетAddIn - произвольный. Единственное условие - он должен совпадать в приведенных выше вызовах.
Строка AddInNativeExtension - уже указана в шаблоне компоненты (RegisterExtensionAs), ее не надо менять.
Переменную МояКомпонента рекомендуется описать в модуле управляемого и обычного приложения как Перем МояКомпонента Экспорт.

Шаг 5. Вызов методов компоненты:

       Результат = МояКомпонента.ReadAllXml();

Шаг 6. Пожать себе руку за успешное подключение компоненты к 1С.

Полный пример подключения компоненты:

Процедура Команда1(Команда)  
	
	УстановитьВнешнююКомпоненту("ОбщийМакет.МойМакет");
	ПодключитьВнешнююКомпоненту("ОбщийМакет.МойМакет", "МойМакетAddIn", ТипВнешнейКомпоненты.Native); 
        МояКомпонента = Новый("AddIn.МойМакетAddIn.AddInNativeExtension");

	Результат = МояКомпонента.ReadAllXml();
	 	 	
КонецПроцедуры

Подготовительные операции

Решить:

NativeAPI сама стучится в плагин и потом ждать результат через события В момент подключения, NativeAPI устанавливает соединение с СБИС3 Плагин, по этому до отправки первой команды нужно убедиться, что данное подключение установлено дождавшись событие "connected" (type=Event, data.eventName=connected). . Подробнее см. в разделе Получение и обработка событий.

ExtSdk2 является расширением (модулем) СБИС3 Плагин. При обращении к модулю плагина требуется указывать идентификатор модуля. Получить идентификатор ExtSdk2 можно при помощи команды МояКомпонента.GetModule.

Кроме идентификатора модуля, для отправки команд в ExtSdk2 вызывающая сторона (клиент) должен быть аутентифицирован. Для аутентификации в ExtSdk2 доступны несколько вариантов. Результатом аутентификации является полученный идентификатор сессии который следует передавать при каждом вызове ExtSdk2 (допускается на одном соединении вызов команд из разных сессий).

Важно! Рекомендуется хранить данный идентификатор сессии между подключениями и вызывать аутентификацию только при получении ошибки аутентификации.

Вызов команд

Все вызовы СБИС3 Плагин асинхронны - вы отправляете команду и ждете сообщения о результатах выполнения команды. Для отправки команды, нужно вызвать метод МояКомпонента.CallMethodXML (исключение составляют команды аутентификации, их следует вызывать при помощи метода CallMethodWithoutAuthXML). В ответ вы получите идентификатор запроса (UUID), данный идентификатор будет присутствовать в событии ответа и по нему вы сможете понять к какому запросу относится данное событие.

Со списком всех доступных команд Вы можете ознакомиться. В изложены наиболее оптимальные алгоритмы работы с ExtSdk2.

Получение и обработка событий

Работа с ExtSdk2 и СБИС3 Плагин осуществляется асинхронно, т.е. в ответ на ваш вызов Вы получите только его идентификатор, а не результат или ошибку. Для получения результата требуется делать периодический вызов функции МояКомпонента.ReadAllXml. Данная функция возвращает все события которые поступили от плагина с момента последнего вызова этой функции (или запуска плагина если это первый вызов). Между вызовами ReadAllXml необходимо делать таймаут 100-500мс, для этого можно воспользоваться методом МояКомпонента.Sleep

По мимо событий содержащих результат вызова команды, в NativeAPI Объект могут приходить события содержащие прогресс выполнения длительной операции (например загрузки больших файлов) или события произошедшие в СБИС, например распознавание документа и т.п. В интеграционных модулях рекомендуется построить обработку событий на принципах регистрации и вызова обработчика обратного вызова. Интеграционный модуль должен игнорировать не интересующие или неожиданные события.

Кроме асинхронных вызовов, сами команды ExtSdk2 могут выполняться асинхронно. В основном это касается методов отправки. Такие методы в качестве ответа возвращают специальный тип ошибки Error #ASYNC. Результат выполнения приходит отдельным событием Event #ASYNC. Такой подход обусловлен тем, что изначально предполагалось исключительно синхронное выполнение методов внутри СБИС3 Плагин.

Более подробно о событиях