AXForum  
Go Back   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Forgotten Your Password?
Register Forum Rules FAQ Members List Today's Posts Search

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

Кто-нибудь может посоветовать как лучше решить такую задачу в Аксапте? Может кто-то уже решал подобные задачи в Аксапте, поделитесь опытом.
Old 07.03.2006, 16:17   #2  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 5
можно попробовать XMLHttpRequest в асинхронном режиме и по таймеру или в цикле проверять завершился он или нет.
База знаний ERP : Axapta / Взаимодействие С Окружением
This post has been rated by: Logger (3).
Old 09.03.2006, 09:26   #3  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 21.10.2004
Quote:
Originally Posted by belugin
и по таймеру или в цикле проверять завершился он или нет.
Можно по подробнее с этого места:
По-моему такая схема будет работать если сервис один, если сервисов несколько, то:
Если опрашивать сервисы в цикле, то не получается сделать запрос к следующему сервису, пока предыдущий не вернул результат.
По таймеру тоже не получается, т.к. таймер только один, а как сделать в Аксапте 10 независимых друг от друга таймеров?
Old 09.03.2006, 09:31   #4  
belugin is offline
belugin
Участник
belugin's Avatar
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Join Date: 16.01.2004
Blog Entries: 5
Quote:
Originally Posted by Lucky13
Можно по подробнее с этого места:
По-моему такая схема будет работать если сервис один, если сервисов несколько, то:
Если опрашивать сервисы в цикле, то не получается сделать запрос к следующему сервису, пока предыдущий не вернул результат.
Почему? Завести список HTTPRequest'ов и опрашивать все по очереди.
Quote:
По таймеру тоже не получается, т.к. таймер только один, а как сделать в Аксапте 10 независимых друг от друга таймеров?
по-моему, сколько раз вызвал setTimeOut столько и таймеров.
Old 09.03.2006, 11:49   #5  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 21.10.2004
Кажется я понял свою ошибку: setTimeOut не выполняет функцию сразу, а выполняет через n миллисекунд, укзанных во втором параметре. Я этого не учел. Теперь все работает
Old 05.12.2014, 10:07   #6  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
Quote:
Originally Posted by Lucky13 View Post
Аксапта обращается к этим сервисам с помощью WinInet и полученные данные сохраняет во временной таблице.
Если не сложно, можно предоставить пример как у вас Аксапта общается с сервисами с помощью WinInet.
Old 07.12.2014, 16:58   #7  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Kabardian's Avatar
 
424 / 338 (12) ++++++
Join Date: 14.12.2008
Location: Москва
Blog Entries: 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/

Last edited by Kabardian; 07.12.2014 at 17:07.
Old 08.12.2014, 08:56   #8  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
Спасибо за ответ.
У меня 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 файл?
Old 08.12.2014, 09:29   #9  
Player1 is offline
Player1
Участник
Самостоятельные клиенты AX
 
306 / 137 (5) +++++
Join Date: 21.04.2008
Может подойдет пример из Tutorial_XMLPost, там используется класс XMLHTTPRequest
Old 08.12.2014, 09:43   #10  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
У меня нет такого туториала, кстати как и класса XMLHTTPRequest. Поделитесь xpo-шником?
Old 08.12.2014, 09:43   #11  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 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 зависит от того, что вернет сервер

Еще зависит от того есть прокси сервер или нет. Если есть, то с ним тоже придется повозиться с параметрами
Old 08.12.2014, 09:47   #12  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Kabardian's Avatar
 
424 / 338 (12) ++++++
Join Date: 14.12.2008
Location: Москва
Blog Entries: 14
Если хотите использовать именно WinInet лучше на MSDN описание работы и примеры использования класса посмотреть для начала:
Using the WinINet Functions to Access the WWW
Quote:
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.
Old 08.12.2014, 10:08   #13  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
Спасибо за ответы.
Quote:
Originally Posted by Lucky13 View Post
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?

Last edited by smailik; 08.12.2014 at 10:12.
Old 08.12.2014, 10:29   #14  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 21.10.2004
Quote:
Originally Posted by smailik View Post
Спасибо за ответы.

Это по памяти написано или прямой копипаст из кода?
у меня нет методов 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, только он прокси-сервер не понимает

Last edited by Lucky13; 08.12.2014 at 10:37.
This post has been rated by: smailik (1).
Old 08.12.2014, 16:02   #15  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
Quote:
Originally Posted by Lucky13 View Post
[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
    }
что то делаю не так?
Old 09.12.2014, 00:23   #16  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Kabardian's Avatar
 
424 / 338 (12) ++++++
Join Date: 14.12.2008
Location: Москва
Blog Entries: 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.
This post has been rated by: smailik (1).
Old 09.12.2014, 11:21   #17  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 21.10.2004
Quote:
Originally Posted by smailik View Post
У меня в new internerOpen не вызывается, т.е не прописано
Возможно в 2009 по другому сделано, но функции winInet от этого не меняются. internetOpen вы, скорее всего вызвали правильно, далее internetConnect. Она должна получать handle, который вернула internetOpen, так как в new она у вас не вызывается, то как он передается в internetConnect? Далее я писал:
Quote:
servername - адрес сервера (напр www.yandex.ru или ip) без http
а у вас как? Что за параметры XXX непонятно. Посмотрите не методы класса WinInet, а то, что в них написано и какие туда параметры отдаются.Что-то типа этого:
X++:
    return _internetConnect.call(hdl, serverName, port, _login, _pass, mode, 0, 0);
И зачем вы в OpenRequest опять весь адрес отдаете?
Old 09.12.2014, 13:21   #18  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
Quote:
Originally Posted by Kabardian View Post
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. В этом примере собираюсь передать только заголовок. но пока возвращает только нули
Old 09.12.2014, 14:59   #19  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Join Date: 21.10.2004
Quote:
Originally Posted by smailik View Post
В этом примере собираюсь передать только заголовок. но пока возвращает только нули
Посмотрите что в методе internetConnect. Туда должен передаваться handle, url сервера, порт, логин, пароль, режим доступа. Я чуть раньше приводил вызов. У вас только 3 параметра при вызове, а в качестве остальных что передается? Порт через двоеточие в адресе не нужен. Если конечно эта строка в методе не парсится.
Old 09.12.2014, 15:38   #20  
smailik is offline
smailik
Участник
smailik's Avatar
 
250 / 70 (3) ++++
Join Date: 10.04.2012
Location: Москва
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, но на этом все.
Tags
settimeout, webservice

 

Similar Threads
Thread Thread Starter Forum Replies Last Post
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Рейтинг@Mail.ru
All times are GMT +3. The time now is 10:20.
Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Contacts E-mail, Advertising.