AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.03.2006, 15:27   #1  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Обращение к http-сервису в Аксапте
Имеется несколько http сервисов (больше 10). Время обработки запроса сервисом 3-5 сек. Аксапта обращается к этим сервисам с помощью WinInet и полученные данные сохраняет во временной таблице. Таким образом, на запрос к 10 сервисам, при последовательном обращении, уходит 30-50 сек. Хотелось бы отсылать 10 запросов сразу, а не последовательно, вот только как в Аксапте реализовать многопоточность?

Кто-нибудь может посоветовать как лучше решить такую задачу в Аксапте? Может кто-то уже решал подобные задачи в Аксапте, поделитесь опытом.
Старый 07.03.2006, 16:17   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
можно попробовать XMLHttpRequest в асинхронном режиме и по таймеру или в цикле проверять завершился он или нет.
База знаний ERP : Axapta / Взаимодействие С Окружением
За это сообщение автора поблагодарили: Logger (3).
Старый 09.03.2006, 09:26   #3  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Цитата:
Сообщение от belugin
и по таймеру или в цикле проверять завершился он или нет.
Можно по подробнее с этого места:
По-моему такая схема будет работать если сервис один, если сервисов несколько, то:
Если опрашивать сервисы в цикле, то не получается сделать запрос к следующему сервису, пока предыдущий не вернул результат.
По таймеру тоже не получается, т.к. таймер только один, а как сделать в Аксапте 10 независимых друг от друга таймеров?
Старый 09.03.2006, 09:31   #4  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Lucky13
Можно по подробнее с этого места:
По-моему такая схема будет работать если сервис один, если сервисов несколько, то:
Если опрашивать сервисы в цикле, то не получается сделать запрос к следующему сервису, пока предыдущий не вернул результат.
Почему? Завести список HTTPRequest'ов и опрашивать все по очереди.
Цитата:
По таймеру тоже не получается, т.к. таймер только один, а как сделать в Аксапте 10 независимых друг от друга таймеров?
по-моему, сколько раз вызвал setTimeOut столько и таймеров.
Старый 09.03.2006, 11:49   #5  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Кажется я понял свою ошибку: setTimeOut не выполняет функцию сразу, а выполняет через n миллисекунд, укзанных во втором параметре. Я этого не учел. Теперь все работает
Старый 05.12.2014, 10:07   #6  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Цитата:
Сообщение от Lucky13 Посмотреть сообщение
Аксапта обращается к этим сервисам с помощью WinInet и полученные данные сохраняет во временной таблице.
Если не сложно, можно предоставить пример как у вас Аксапта общается с сервисами с помощью WinInet.
Старый 07.12.2014, 16:58   #7  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Аватар для Kabardian
 
424 / 338 (12) ++++++
Регистрация: 14.12.2008
Адрес: Москва
Записей в блоге: 14
Если это в AX 2012, смотрите в сторону пакетной обработки. Разработайте периодическую операцию с поддержкой пакетной обработки и выделите там 10 задач (task), тогда при пакетной обработке эти 10 задач будут выполняться одновременно. Единственное совокупное время обработки задачи будет зависеть от самого длительно выполняющегося задания.


upd: пару ссылок по теме:
http://blogs.msdn.com/b/axperf/archi...ax-part-i.aspx
https://axconsultant.wordpress.com/2...h-job-ax-2012/

Последний раз редактировалось Kabardian; 07.12.2014 в 17:07.
Старый 08.12.2014, 08:56   #8  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Спасибо за ответ.
У меня Ax 2009. Собственно меня не интересует параллельная обработка. Мне бы обычную однопоточную сделать. Я этим занялся впервые и хотелось бы вообще увидеть как отправлять запросы.
Сейчас я вот на каком этапе
X++:
    s = "url:/rest/2/authentication/createSession?account=ACCOUNT&login=LOGIN.dispatcher&password=PASSWORD";    
    code1 = winInet.internetOpen("xxx.xxx.xxx.xxx", 1, "xxx", "xxx", 0); // 1 и 0 поставил от балды
    code2 = winInet.internetConnect("xxx.xxx.xxx.xxx", "xxx", "xxx");
    code3 = winInet.httpOpenRequest(code1, "POST", s);    
    info (strfmt("%1 %2 %3", code1, code2, code3));
в code1 есть какой-то ответ
в code2 0, в code 3 тоже 0
Если правильно понимаю то при провальной работе вместо S нужно подсунуть xml файл?
Старый 08.12.2014, 09:29   #9  
Player1 is offline
Player1
Участник
Самостоятельные клиенты AX
 
306 / 137 (5) +++++
Регистрация: 21.04.2008
Может подойдет пример из Tutorial_XMLPost, там используется класс XMLHTTPRequest
Старый 08.12.2014, 09:43   #10  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
У меня нет такого туториала, кстати как и класса XMLHTTPRequest. Поделитесь xpo-шником?
Старый 08.12.2014, 09:43   #11  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
X++:
WinInet winInet = new WinInet(...); //internetOpen вызывается в new
int hURL;
int hReq;
int res;
str ret;

 if (winInet.ok())
 {
        hURL = winInet.internetConnect(servername,80);
        hReq = winInet.OpenRequest(hURL, url, 'POST');
        res = winInet.SendRequest(hReq, hdr, data);
        ret = winInet.internetReadFile(hReq);
 }
Важно не столько как функции вызывать, а какие параметры передавать.
servername - адрес сервера (напр www.yandex.ru или ip) без http
url - путь на сервере (если нужен)
hdr - заголовок (зависит от сервера)
data - это передаваемые данные, в вашем случае xml
ret - ответ сервера

res должен быть равен 1, ret зависит от того, что вернет сервер

Еще зависит от того есть прокси сервер или нет. Если есть, то с ним тоже придется повозиться с параметрами
Старый 08.12.2014, 09:47   #12  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Аватар для Kabardian
 
424 / 338 (12) ++++++
Регистрация: 14.12.2008
Адрес: Москва
Записей в блоге: 14
Если хотите использовать именно WinInet лучше на MSDN описание работы и примеры использования класса посмотреть для начала:
Using the WinINet Functions to Access the WWW
Цитата:
Using the WinINet Functions to Access the WWW

Initiating a Connection to the WWW
Opening a Request
Adding Request Headers
Sending a Request
Posting Data to the Server
Getting Information About a Request
Downloading Resources from the WWW
Если обработка планируется на стороне сервера АОС, лучше смотреть в сторону WinHTTP, см. также сравнение:
WinINet vs. WinHTTP.
Старый 08.12.2014, 10:08   #13  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Спасибо за ответы.
Цитата:
Сообщение от Lucky13 Посмотреть сообщение
X++:
WinInet winInet = new WinInet(...); //internetOpen вызывается в new
int hURL;
int hReq;
int res;
str ret;

 if (winInet.ok())
 {
        hURL = winInet.internetConnect(servername,80);
        hReq = winInet.OpenRequest(hURL, url, 'POST');
        res = winInet.SendRequest(hReq, hdr, data);
        ret = winInet.internetReadFile(hReq);
 }
Это по памяти написано или прямой копипаст из кода?
у меня нет методов winInet.OpenRequest и winInet.SendRequest. У меня есть winInet.httpSendRequest но у него порядок аргументов другой и один аргумент отличается
X++:
boolean  httpSendRequest(int _handler, BinData _file, int _size)
{
    return _httpSendRequest.call(_handler, "Content-Type: application/x-www-form-urlencoded", 47, _file, _size);
}
Если это прямой копипаст можете выслать свой класс WinInet?

Последний раз редактировалось smailik; 08.12.2014 в 10:12.
Старый 08.12.2014, 10:29   #14  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Цитата:
Сообщение от smailik Посмотреть сообщение
Спасибо за ответы.

Это по памяти написано или прямой копипаст из кода?
у меня нет методов winInet.OpenRequest и winInet.SendRequest.
Это копипаст. В стандартном классе WinInet таких методов нет, но без них POST не сделаешь, их нужно добавить. Посмотрите как сделаны другие методы этого класса и сделайте также. У меня 3.0, возможно в 2009 эти методы есть, только по другому называются.
Примерно вот так:
X++:
    _httpOpenRequest = new DLLFunction(_winInet, 'HttpOpenRequestA');
    _httpOpenRequest.returns(ExtTypes::DWord);
    _httpOpenRequest.arg(ExtTypes::DWORD);
    _httpOpenRequest.arg(ExtTypes::String);
    _httpOpenRequest.arg(ExtTypes::String);
    _httpOpenRequest.arg(ExtTypes::String);
    _httpOpenRequest.arg(ExtTypes::String);
    _httpOpenRequest.arg(ExtTypes::DWORD);
    _httpOpenRequest.arg(ExtTypes::DWORD);
    _httpOpenRequest.arg(ExtTypes::DWORD);

    _httpSendRequest = new DLLFunction(_winInet, 'HttpSendRequestA');
    _httpSendRequest.returns(ExtTypes::DWord);
    _httpSendRequest.arg(ExtTypes::DWord);
    _httpSendRequest.arg(ExtTypes::String);
    _httpSendRequest.arg(ExtTypes::DWord);
    _httpSendRequest.arg(ExtTypes::String);
    _httpSendRequest.arg(ExtTypes::DWord);

int OpenRequest(int hdl, str _url, str _verb = "POST", int flags = 0)
{
    ;
    return _httpOpenRequest.call(hdl, _verb, _url, '', '', 0, flags, 0);
}

int SendRequest(int handle, str hdr, str data)
{
    ;
    return _httpSendRequest.call(handle, hdr, strlen(hdr), data, strlen(data));
}
Либо воспользуйтесь классом XMLHTTPRequest, только он прокси-сервер не понимает

Последний раз редактировалось Lucky13; 08.12.2014 в 10:37.
За это сообщение автора поблагодарили: smailik (1).
Старый 08.12.2014, 16:02   #15  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Цитата:
Сообщение от Lucky13 Посмотреть сообщение
[xpp]
WinInet winInet = new WinInet(...); //internetOpen вызывается в new
У меня в new internerOpen не вызывается, т.е не прописано
X++:
strData = "url:/rest/2/authentication/createSession?account=ХХХ&login=ХХХ.dispatcher&password=ХХХ";
    url = "http://review.maxoptra.com/";
    if (winInetLocal.ok())
    {
        hURL = winInetLocal.internetOpen("http://review.maxoptra.com/", 1, "ХХХ", "ХХХ", 0); // вот тут ответ число есть
        hURL = winInetLocal.internetConnect("http://review.maxoptra.com/", "ХХХ", "ХХХ"); // а вот тут ответ 0
        hReq = winInetLocal.httpOpenRequest(hURL, url, 'POST');
        res = winInetLocal.httpSendRequest(hReq, hdr, strData); // и тут все по нулям
        ret = winInetLocal.internetReadFile(hReq); // и тут 0
    }
что то делаю не так?
Старый 09.12.2014, 00:23   #16  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Аватар для Kabardian
 
424 / 338 (12) ++++++
Регистрация: 14.12.2008
Адрес: Москва
Записей в блоге: 14
smailik, а почему именно WinInet? Этого класса даже нет в стандартной AX 2009, подозреваю у вас доработка/апгрейд класса с AX 3.0/4.0.

Вот то же самое, но используя сборки .NET и класс WebRequest:
X++:
static void MicrosoftWebRequestSample(Args _args)
{
    System.Net.WebRequest           webRequest;
    System.Net.ICredentials         credentialCache;
    System.Net.HttpWebResponse      httpWebResponse;

    System.IO.Stream                stream;
    System.IO.StreamReader          streamReader;
    
    str postData;
    System.Byte[] byteArray;
    System.Text.Encoding    encodingUTF8;
    
    str statusDescription;
    str responseFromServer;
    ;

    //1. Создать запрос.
    webRequest = System.Net.WebRequest::Create("http://httpbin.org/post"); //этот веб-сервис отправляет в ответ данные, которые были направлены ему.
    webRequest.set_Method("POST");
    
    //2. Ввести данные к отправке и ковертировать их в массив байтов
    postData = "url:/rest/2/authentication/createSession?account=ХХХ&login=ХХХ.dispatcher&password=ХХХ";
    encodingUTF8 = System.Text.Encoding::get_UTF8();
    byteArray = encodingUTF8.GetBytes(postData);
    
    //3. Изменить свойства запроса: ContentType, ContentLength.
    webRequest.set_ContentType("application/x-www-form-urlencoded");
    webRequest.set_ContentLength(byteArray.get_Length());
    
    //4. Если требуется авторизация, то указать учетные данные.
    credentialCache =  System.Net.CredentialCache::get_DefaultCredentials();

    //5. Получить поток с данными.
    stream = webRequest.GetRequestStream();
    
    //6. Записать поток данных.
    stream.Write(byteArray, 0, byteArray.get_Length());
    
    //7. Закрыть поток.
    stream.Close();
    
    //8. Получить ответ.
    httpWebResponse = webRequest.GetResponse();

    //9. Отобразить статус.
    statusDescription = httpWebResponse.get_StatusDescription();
    info(strFmt("%1", statusDescription));

    //10. Получить поток с данными.
    stream = httpWebResponse.GetResponseStream();

    //11. Открыть поток с помощью StreamReader.
    streamReader = new System.IO.StreamReader(stream);

    //12. Прочитать содержимое.
    responseFromServer = streamReader.ReadToEnd();

    //13. Вывести содержимое в инфолог.
    info(strFmt("%1", responseFromServer));

    //14. Закрыть все.
    streamReader.Close();
    stream.Close();
    httpWebResponse.Close();
}
Там тестовый веб-сервис, он в ответ сразу отправляет данные, отправленные ему. У меня сейчас работает, проверьте может решение подойдет.

Честно содрал пример у Microsoft отсюда: http://msdn.microsoft.com/en-us/libr...v=vs.110).aspx.
За это сообщение автора поблагодарили: smailik (1).
Старый 09.12.2014, 11:21   #17  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Цитата:
Сообщение от smailik Посмотреть сообщение
У меня в new internerOpen не вызывается, т.е не прописано
Возможно в 2009 по другому сделано, но функции winInet от этого не меняются. internetOpen вы, скорее всего вызвали правильно, далее internetConnect. Она должна получать handle, который вернула internetOpen, так как в new она у вас не вызывается, то как он передается в internetConnect? Далее я писал:
Цитата:
servername - адрес сервера (напр www.yandex.ru или ip) без http
а у вас как? Что за параметры XXX непонятно. Посмотрите не методы класса WinInet, а то, что в них написано и какие туда параметры отдаются.Что-то типа этого:
X++:
    return _internetConnect.call(hdl, serverName, port, _login, _pass, mode, 0, 0);
И зачем вы в OpenRequest опять весь адрес отдаете?
Старый 09.12.2014, 13:21   #18  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Цитата:
Сообщение от Kabardian Посмотреть сообщение
smailik, а почему именно WinInet? Этого класса даже нет в стандартной AX 2009, подозреваю у вас доработка/апгрейд класса с AX 3.0/4.0.
да в Ax 2009 этого класса нет, нашел где то на форуме xpo-шник. Пару методов переправлял. WinInet одно из первых на что наткнулся, на нем было много различных, но не подходящих мне примеров Пример у вас шикарный спасибо. Попробовал через него, почему то мне такая хрень возвращается пока с этим разбираюсь
X++:
hdr = "http://review.maxoptra.com/rest/2/authentication/createSession?accountID=XXX&user=XXX&password=XXX";
    url = "";
    strData = "";
    if (winInetLocal.ok())
    {
        //hnd  = winInetLocal.internetOpen("5.9.157.231:80", 1, "XXX", "XXX", 0); // ответ не 0
        hURL = winInetLocal.internetConnect("5.9.157.231:80", "XXX", "XXX"); // 0
        hReq = winInetLocal.httpOpenRequest(hURL, url, 'POST'); // 0
        res = winInetLocal.httpSendRequest(hReq, hdr, strData); // 0
        ret = winInetLocal.internetReadFile(hReq); // 0
    }
XXX - это типа маскировка логина пароля и аккаунта.
порылся порылся и нашел _handle = this.internetOpen("Axapta",0,"","",0); в new. В этом примере собираюсь передать только заголовок. но пока возвращает только нули
Старый 09.12.2014, 14:59   #19  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Цитата:
Сообщение от smailik Посмотреть сообщение
В этом примере собираюсь передать только заголовок. но пока возвращает только нули
Посмотрите что в методе internetConnect. Туда должен передаваться handle, url сервера, порт, логин, пароль, режим доступа. Я чуть раньше приводил вызов. У вас только 3 параметра при вызове, а в качестве остальных что передается? Порт через двоеточие в адресе не нужен. Если конечно эта строка в методе не парсится.
Старый 09.12.2014, 15:38   #20  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
X++:
int internetConnect(str 60 _server, str 99 _userName, str 99 _password )
{
    return _internetConnect.call(_handle,_server, 80,_userName,_password,1,0,0);
}
_handle не пустой, _server, _userName, _password передаются все хорошо, смотрел в отладчике во время прохождения строки
X++:
hURL = winInetLocal.internetConnect("review.maxoptra.com", "XXX", "XXX");
Ax подвисает секунд на 20, но на этом все.
Теги
settimeout, webservice

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Standart Costing, Direct Costing и механизмы их реализации в Аксапте slava09 DAX: Функционал 55 05.06.2006 11:00
Система оповещений в Аксапте (события в Аксапте) raunio DAX: Прочие вопросы 1 29.09.2005 15:44
Аналитический учет в Аксапте. Анна DAX: Прочие вопросы 38 06.04.2005 14:04
Размышления на тему “Системы контроля версий в Аксапте”. Андре DAX: База знаний и проекты 31 07.02.2005 12:29
Скорость в Аксапте Алексей Контев DAX: Прочие вопросы 13 25.06.2002 14:37

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:37.