GSOAP का उपयोग करके C ++ में SOAP क्लाइंट लिखना

ऐसा हुआ कि हब पर gSOAP के साथ काम करना बहुत खराब तरीके से वर्णित है। सिर्फ एक पद , ईमानदार होना। लेकिन यह एक वेब सेवा के निर्माण का वर्णन करता है, लेकिन ग्राहक अनुप्रयोगों के बारे में क्या? बहुत समय पहले नहीं, मुझे SOAP का उपयोग कर एक दूरस्थ सर्वर के साथ काम को व्यवस्थित करने के कार्य का सामना करना पड़ा - और मैंने इस बारे में एक छोटा लेख लिखने का फैसला किया।
क्योंकि मैं wsdl फाइलें प्रदान नहीं कर सकता, जिसके साथ मैं काम कर रहा था (NDA और वह सब), तब मैंने परीक्षण के लिए उपयुक्त सेवाओं की तलाश शुरू की। दो मुझे दिलचस्प लगे:

http://www.webservicex.net/ValidateEmail.asmx?WSDL
http://www.webservicex.net/country.asmx?WSDL

मुझे अभी भी पता नहीं चल पाया है कि wsdl फ़ाइलों को कहाँ से डाउनलोड किया जाए, इसलिए मैंने उनकी सामग्री की प्रतिलिपि बनाई और उन्हें ValidateEmail.wsdl और country.wsdl नामों के तहत सहेजा।
आप यहाँ gSOAP को डाउनलोड कर सकते हैं - http://www.cs.fsu.edu/~engelen/soap.html । आप एक ही पते पर gSOAP के बारे में पढ़ सकते हैं।

लेखन के समय का नवीनतम संस्करण 2.8.14 है

चलो काम पर लग जाओ। दो बहुत ही महत्वपूर्ण उपयोगिताओं gsoap \ bin \ win32 \ फ़ोल्डर में रहते हैं। सबसे पहले, हम wsdl2h.exe में रुचि रखते हैं। आप मदद का उपयोग करके इसके बारे में अधिक जान सकते हैं:
> wsdlh2.exe -h
इसे निम्नलिखित मानकों के साथ चलाएं:
wsdl2h.exe -o emailAndCountry.h ValidateEmail.wsdl देशवॉटल
सब कुछ काफी सरल है, हमने केवल आउटपुट फ़ाइल का नाम और wsdl फ़ाइलों की सूची निर्दिष्ट की है जिसके साथ हम काम करना चाहते हैं।
उसके बाद, हम सीधे C ++ कक्षाओं के लिए कोड तैयार करते हैं:
साबुनकैप 2.exe -C -dgSoap -j -L -x -I "ADDRESS_TO_GSOAP \ gsoap-2.8 \ gsoap \ import" emailAndCountry.h
-सी स्विच कहता है कि केवल क्लाइंट कोड जेनरेट करना होगा।
-dgSoap gSoap फ़ोल्डर में सभी फ़ाइलों को डालने के लिए कहता है (आपको इसे पहले बनाने की आवश्यकता है)। हम लिबर फाइल उत्पन्न नहीं करते हैं और साबुन संरचना से विरासत में नहीं मिलते हैं; -x स्विच आपको नमूना संदेशों के साथ XML फ़ाइलों को उत्पन्न नहीं करने के लिए कहता है। हम gSOAP के साथ फ़ोल्डर का पता और उस फ़ाइल को निर्दिष्ट करते हैं जिसे हम पार्स करेंगे और उसके आधार पर हम कोड उत्पन्न करते हैं।
विभिन्न संस्करणों के gSOAP अलग कोड (जो तार्किक रूप से, सामान्य रूप से) उत्पन्न कर सकते हैं, और यहां तक ​​कि फ़ाइलों की संरचना भी भिन्न होगी। यह याद रखना महत्वपूर्ण है कि क्या आप अचानक एक बिल्ड सर्वर पर gSOAP फ़ाइलों को उत्पन्न करना चाहते हैं, और उन्हें एक संस्करण नियंत्रण प्रणाली में संग्रहीत नहीं करते हैं।
GSoap फ़ोल्डर में सभी जोड़तोड़ के बाद, हम कई नई फाइलें देखते हैं। ये प्लस -h और -cpp फाइलें हैं, साथ ही देशसो.ऐपमैप और वैलिडेट ईमेलसोअप .nsmap। वे मेल खाते हैं, आप उनकी सामग्री को एक में सहेज सकते हैं (उदाहरण के लिए, namespaces.nsmap), और उन्हें हटा दें। namepaces.nsmap को प्रोजेक्ट में शामिल करने की आवश्यकता है। आमतौर पर, यह किसी प्रकार के सहायक वर्ग में किया जाता है जो gSOAP के साथ काम करेगा। हां, इस तरह का वर्ग निश्चित रूप से मौजूद होगा।

उसके बाद, stdsoap2.h और stdsoap2.cpp को gSoap फ़ोल्डर में जोड़ें - उन्हें साबुनStub.h में शामिल किया जाएगा

परियोजना के लिए संपूर्ण फ़ोल्डर जोड़ें और काम करना शुरू करें :)
हम वर्गों को देखतें हैं cccryrySoapProxy.cpp और soapValidateEmailSoapProxy.cpp; in * _init मेथड्स (साबुन_मोड इमोड, सोप_मोड ओमोड) - नेमपेस को हटा दें (हमने जानबूझकर हमारे नेमपेस.नाममैप को शामिल किया)।

चलो ईमेल सत्यापन सुविधा के साथ शुरू करते हैं - gSoap / साबुनValidateEmailSoapProxy.h
हम विधि में रुचि रखते हैं
वर्चुअल int

इस फ़ंक्शन के तर्कों का विवरण देखें:
class SOAP_CMAC _ns1__IsValidEmail { public: std::string *Email; /* optional element of type xsd:string */ struct soap *soap; /* transient * …./ 


* ईमेल क्षेत्र संभवतः काम में आएगा।

हम इस वर्ग की एक वस्तु बनाते हैं और उस वस्तु को निर्दिष्ट करते हैं जिसे हम जाँचेंगे
 _ns1__IsValidEmail isValidEmailRequest; std::string CHECKED_E_MAIL("pisem@sovsem.net"); isValidEmailRequest.Email = &CHECKED_E_MAIL; 


तुरंत एक वस्तु बनाएं जिसमें परिणाम आएगा:
 _ns1__IsValidEmailResponse isValidEmailResponse; 

हम देखते हैं कि परिणाम बूल IsValidEmailResult फ़ील्ड में होगा।

हम सर्वर को एक अनुरोध भेजते हैं:
 const int gSoapResult = validateEmailProxy.IsValidEmail(&isValidEmailRequest, &isValidEmailResponse); 


हम उस स्निफर को देखते हैं जो हमने भेजा था:
 <?xml version="1.0" encoding="UTF-8" ?> - <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://www.webservicex.net" xmlns:ns2="http://www.webserviceX.NET"> - <SOAP-ENV:Body> - <ns1:IsValidEmail> <ns1:Email>pisem@sovsem.net</ns1:Email> </ns1:IsValidEmail> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 


हम उत्तर को देखते हैं - हम देखते हैं कि परिणाम क्षेत्र गलत है। स्निफर इसकी पुष्टि करता है।

हम एक और पता आज़माते हैं - press@fsb.ru

मुझे तुरंत पता चलेगा कि सर्वर कुछ समय के लिए सोचता है, लेकिन यह शायद ही इस पते से सत्यापित है।
लेकिन जवाब फिर भी आता है, और यह पता हमारे लिए अमान्य माना जाता है।
खैर, स्पष्ट रूप से "बुरा" पता आज़माएँ - "1354 @"

प्रमुख समय अनंत काल है। यह वास्तव में बहुत लंबे समय तक काम करता है।
लगभग एक मिनट के बाद, मैं इंतजार कर के थक गया था, और मैंने वैध पते की जांच करने के लिए फिर से कोशिश करने का फैसला किया - adv@thematicmedia.ru
ठीक है, परिणाम गलत है।
adv @ विषयगत - असत्य
adv @ ल - असत्य
मैंने अपने प्राचीन मेलबॉक्सों में से एक को आज़माया - सर्वर फिर से सोच रहा था। लंबे समय तक। लेकिन फिर भी उसने जवाब दिया - झूठा।

खैर, यह पता चला है कि समस्या केवल सर्वर में है, हमारा कोड सर्वर प्रतिक्रियाओं को सही तरीके से भेजता है। कोड काम करता है, लेकिन पूरी तरह से बेकार है।

हम दूसरी श्रेणी की कोशिश करते हैं - देशोपासपॉक्सी
उनके तरीकों की संख्या बहुत बड़ी है, आप उन्हें हेडर में देख सकते हैं।
हम GetCountryByCountryCode के साथ शुरू करते हुए, उन्हें क्रम में परखेंगे:
 _ns2__GetCountryByCountryCode getCountryByCountryCodeRequest; std::string COUNTRY_CODE("GB"); getCountryByCountryCodeRequest.CountryCode = &COUNTRY_CODE; _ns2__GetCountryByCountryCodeResponse getCountryByCountryCodeResponse; countrySoapProxy countryProxy; const int gSoapResult = countryProxy.GetCountryByCountryCode(&getCountryByCountryCodeRequest, &getCountryByCountryCodeResponse); if (gSoapResult != SOAP_OK) { std::cout << "FAIL" << std::endl; return 0; } 


उत्तर मिला:
 <NewDataSet> <Table> <countrycode>gb</countrycode> <name>Great Britain</name> </Table> <Table> <countrycode>gb</countrycode> <name>Great Britain</name> </Table> </NewDataSet> 


मैं मानता हूं, मुझे उम्मीद थी कि उत्तर केवल एक देश होगा, एक स्वस्थ डेटासेट नहीं, बल्कि यह नाइट-पिकिंग है। यह सेवा देश को RU कोड के साथ भी जानती है, चीयर्स!

हम दूसरी विधि से गुजरते हैं:
 _ns2__GetISD getISDRequest; std::string COUNTRY_NAME("Russian Federation"); getISDRequest.CountryName = &COUNTRY_NAME; _ns2__GetISDResponse getISDResponse; countrySoapProxy countryProxy; const int gSoapResult = countryProxy.GetISD(&getISDRequest, &getISDResponse); 


और यह विधि उस तरह से काम करती है, जैसे:

 <NewDataSet> <Table> <code>7</code> <name>Russian Federation</name> </Table> <Table> <code>7</code> <name>Russian Federation</name> </Table> </NewDataSet> 


खैर, इस सेवा के लिए सब कुछ काम करता है, जैसा कि अपेक्षित है, प्रशिक्षण प्रयोजनों के लिए यह पहले की तुलना में थोड़ा अधिक सूट करता है। इस प्रयोग पर अभी रोक लगाई जा सकती है।

जब हम केवल एक सेवा के साथ काम करने जा रहे हैं, जो किसी दिए गए पते पर स्थित है और प्राधिकरण की आवश्यकता नहीं है, तो यह दृष्टिकोण बहुत अच्छा है।
लेकिन हम वेब सेवा को कहीं भी और कभी भी तैनात कर सकते हैं!
वास्तव में, gSoap बहुत कुछ कर सकता है। इसलिए, उदाहरण के लिए, आप लॉगिन पासवर्ड को साबुन संरचना के माध्यम से सेट कर सकते हैं। सबसे सरल मूल प्राधिकरण का एक उदाहरण:
 soap.userid = login; soap.passwd =password; 


साबुन संरचना का वर्णन stdsoap2.h में है:
  const char *userid; /* HTTP Basic authorization userid */ const char *passwd; /* HTTP Basic authorization passwd */ 


आप पता बदल सकते हैं कि किन अनुरोधों को दो तरीकों से भेजा जाएगा: इसे अनुरोध के दौरान ही निर्दिष्ट करें या SOAP प्रॉक्सी बनाते समय इसे निर्दिष्ट करें।
यह सब अपने आप पाठकों से स्पष्ट है:
 virtual int GetISD(_ns2__GetISD *ns2__GetISD, _ns2__GetISDResponse *ns2__GetISDResponse) { return this->GetISD(NULL, NULL, ns2__GetISD, ns2__GetISDResponse); } virtual int GetISD(const char *endpoint, const char *soap_action, _ns2__GetISD *ns2__GetISD, _ns2__GetISDResponse *ns2__GetISDResponse); 


दूसरी विधि के मामले में, हमें इस तरह से एक ऑब्जेक्ट बनाने की आवश्यकता है:
 countrySoapProxy countryProxy("http://www.webservicex.net/country.asmx"); 


कुछ भी जटिल नहीं है, है ना? यहां आप पोर्ट के साथ सामान्य आईपी एड्रेस सेट कर सकते हैं।

मैंने यह भी ध्यान नहीं रखा कि खुद नामस्थान कैसे सेट किया जाए। यह दृष्टिकोण आपको वर्ग नामों के रूप में ns1__IsValidEmail प्राप्त करने की अनुमति देगा, लेकिन ईमेल__IVValidEmail जैसा कुछ। जब कई कक्षाएं होती हैं, तो आप भ्रमित हो सकते हैं। शायद। यह भी समस्याओं के बिना किया जाता है। निम्न प्रारूप की सामग्री के साथ एक फ़ाइल टाइप करें।
myCustomNamespace = " www.webservicex.net "
यानी यह सरल है: नाम और उसका पता निर्दिष्ट करें।

सामान्य तौर पर, gSoap के साथ काम करना विशेष रूप से मुश्किल नहीं है। लेकिन कुछ बिंदु हैं जो इसके साथ काम करते समय पॉप अप करते हैं। इसलिए, उदाहरण के लिए, उपयोगकर्ता नाम और पासवर्ड निर्दिष्ट करते समय, वे अनुरोध के बाद बदल सकते हैं। यानी कोड कुछ इस तरह दिख सकता है:
 countrySoapProxy countryProxy("http://www.webservicex.net/country.asmx"); countryProxy.soap->userid = "login"; countryProxy.soap->passwd = "password"; countryProxy.GetISD(&getISDRequest, &getISDResponse); countryProxy.soap->userid = "login"; countryProxy.soap->passwd = "password"; countryProxy.GetISD(&anotherGetISDRequest, &anotherGetISDResponse); 


यह किसी तरह संदिग्ध लग रहा है।
हो सकता है कि मैंने कुछ को ध्यान में नहीं रखा था, लेकिन gSOAP के साथ एक संक्षिप्त अनुभव एक मिश्रित प्रभाव छोड़ता है: उच्च विकास की गति, अपेक्षाकृत कम मात्रा में कोड - यह सब एक प्लस है। लेकिन यहाँ कोड की एक गड़गड़ाहट है, सी और सी ++ का मिश्रण एक माइनस है। लेकिन मैं मानता हूं कि यह हर किसी के लिए माइनस नहीं है, बल्कि बहुत अधिक प्लसस हैं। किसी भी मामले में, मुझे gSOAP के लिए कोई योग्य विकल्प नहीं मिला - हालांकि मैंने बहुत सावधानी से नहीं खोजा, हमारी कंपनी में परीक्षण किए गए समाधान में भरोसा किया।
यह लेख एक परिचयात्मक लेख से अधिक है जो संक्षेप में gSOAP के साथ शुरू होने के बारे में बात करता है। मैंने यहां अलग-अलग प्राधिकरण तरीके नहीं दिए, मैंने SOAP संरचनाओं से विरासत के मुद्दों का अध्ययन नहीं किया (क्या यह किसी चीज के लिए आवश्यक है?)। कई अनसुलझे सवाल हैं, लेकिन मैंने अभी भी gSOAP को एक संक्षिप्त भ्रमण दिया है, मुझे उम्मीद है। अच्छा काम है!

Source: https://habr.com/ru/post/In174109/


All Articles