gsoap 사용 노트

11046 단어

gsoap 입문


1 gsoap으로 웹 서비스 구축


참고 문서[2]의 소개를 참고하여 약간의 수정이 있었다.

1.1calc 클라이언트 컴파일

  • wsdl 파일에 따라 gsoap용 헤더 파일 생성
  • wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
    
  • 만약에 우리가 만든 웹 서버를 사용한다면 헤더 파일의 아래 코드를 수정하고port 필드를 자신의 웹 서비스 URL로 수정해야 한다.
  • //gsoap ns2  service port:      http://websrv.cs.fsu.edu/~engelen/calcserver.cgi
    

    ... 로 바꾸다
    //gsoap ns2  service port:      http://localhost:9999/cgi-bin/calcserver.cgi
    
  • client proxy 클래스를 생성하는 소스 코드
  • soapcpp2 -j -CL -I/usr/share/gsoap/import calc.h
    
    -j C++ proxy 클래스를 생성하여 client 호출을 제공하고 -CL 클라이언트 프로그램을 생성한다. -I gsoap 관련 헤더 파일 경로를 가리킨다. 이것은 gsoap 설치 위치에 따라 정해진다. 예를 들어 ubuntu가 apt-get를 통해 설치한 gsoap의 경로이다.
  • client 프로그램 작성calcclient.cpp
  • #include "calc.nsmap"      // XML namespace mapping table (only needed once at the global level)
    #include "soapcalcProxy.h" // the proxy class, also #includes "soapH.h" and "soapStub.h"
    int main()
    {
      calcProxy calc;
      double sum;
      if (calc.add(1.23, 4.56, sum) == SOAP_OK)
        std::cout << "Sum = " << sum << std::endl;
      else
        calc.soap_stream_fault(std::cerr);
      calc.destroy(); // same as: soap_destroy(calc.soap);
      soap_end(calc.soap);
    }
    

    proxy클래스calcProxyadd 방법을 호출하여 2개의 매개 변수1.234.56를 전달하여 인쇄 결과를 출력했습니다.
  • 컴파일
  • c++ -o calcclient calcclient.cpp soapC.cpp soapcalcProxy.cpp -lgsoap++
    

    두 번째 단계에서port를 수정하지 않았다면 이때 실행calcclient을 하면 결과를 얻을 수 있습니다. 만약에 port를 수정하면 우리는 자체로calc 서비스를 제공하기 위해 웹 서비스를 구축해야 합니다.

    1.2 서버 구축


    1.2.1 컴파일러 서버 사이드 프로그램

  • client 1단계와 마찬가지로 생성calc.h
  • wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
    
  • 서버단의 인터페이스 클래스 생성
  • soapcpp2 -j -SL -I/usr/share/gsoap/import calc.h
    
  • cgi 프로그램 작성calcserver.cpp,calc 서버 인터페이스 구현
  • #include "calc.nsmap"        // XML namespace mapping table (only needed once at the global level)
    #include "soapcalcService.h" // the service class, also #includes "soapH.h" and "soapStub.h"
    int main()
    {
      calcService calc(SOAP_XML_INDENT);
      if (calc.serve() != SOAP_OK)
        calc.soap_stream_fault(std::cerr);
      calc.destroy(); // same as: soap_destroy(calc.soap);
      soap_end(calc.soap);
    }
    int calcService::add(double a, double b, double &result)
    {
      result = a + b;
      return SOAP_OK;
    }
    int calcService::sub(double a, double b, double &result)
    {
      result = a - b;
      return SOAP_OK;
    }
    int calcService::mul(double a, double b, double &result)
    {
      result = a * b;
      return SOAP_OK;
    }
    int calcService::div(double a, double b, double &result)
    {
      if (b == 0.0)
      {
        char *msg = (char*)soap_malloc(this->soap, 1024);
        snprintf(msg, 1024, "Trying to divide %f by zero", a);
        return this->soap_senderfault(msg, NULL);
      }
      result = a / b;
      return SOAP_OK;
    }
    int calcService::pow(double a, double b, double &result)
    {
      result = ::pow(a, b);
      // soap_errno is like errno, but compatible with Win32
      if (soap_errno == EDOM)
      {
        char *msg = (char*)soap_malloc(this->soap, 1024);
        snprintf(msg, 1024, "Can't take power of %f to %f", a, b);
        return this->soap_senderfault("Power function domain error", msg);
      }
      return SOAP_OK;
    }
    
  • 컴파일, 테스트
  • c++ -o calcserver calcserver.cpp soapC.cpp soapcalcService.cpp -lgsoap++
    ./calcserver < calc.add.req.xml
    

    이때calcserver는 표준 입력에서 soap 명령을 읽고 표준 출력으로 출력하는 cgi 프로그램이다.다음에 웹 서버를 만들어서 cgi 서비스를 제공합니다.

    1.2.2 cgi 서버 구축


    간단하게 말하자면, docker를 사용하여 웹 서버로 아파치를 시작합니다.
  • 아파치 렌즈 다운로드
  • docker pull httpd:2.4
    
  • 수정http.conf 파일에서 아파치 cgi에 대한 지원을 시작합니다.얻다conf 파일, cgi 지원을 수정하고 다음 내용의 주석을 열면 됩니다
  • LoadModule cgi_module modules/mod_cgi.so
    
  • http.conf의 docker container 경로는 다음과 같습니다: /usr/local/apache2/conf/httpd.conf
  • 이 단계를 하지 않으면client를 실행할 때 다음과 같은 오류가 발생합니다. 즉,apache는 cgi 요청을 파일 다운로드 요청으로 간주합니다.
  • Error 200 fault: SOAP-ENV:Client[no subcode]
    "Error 200"
    Detail: [no detail]
    
  • 서비스를 시작하고 calcserverhttp.conf 디렉토리에 다음 명령을 입력합니다.
  • docker run -it --rm --name my-apache-app -p 9999:80 -v "$PWD":/usr/local/apache2/cgi-bin -v "$PWD"/http.conf:/usr/local/apache2/conf/httpd.conf -v /usr/lib/x86_64-linux-gnu/libgsoap++.so.4:/usr/lib/x86_64-linux-gnu/libgsoap++.so.4 httpd:2.4
    

    1.3 기타


    1.3.1 질문


    gsoap도 웹 서버로서 서비스를 제공하는 것을 지원합니다. 서버 코드만 수정하면 됩니다. 그러나 저는 시험에 성공하지 못했습니다.
    int main()
    {
      calcService calc(SOAP_XML_INDENT);
      //if (calc.serve() != SOAP_OK) 

    이 때 서버 프로그램을 실행할 때 항상 알림:
    setsockopt unset IPV6_V6ONLY failed in soap_bind()
    

    1.3.2 curl 디버깅 웹 서비스 서버

    curl 아날로그 클라이언트를 사용하여 soap 서비스를 요청할 수 있습니다[4] 명령은 다음과 같습니다.
    curl -v --header "content-type: application/soap+xml"  --data @calc.add.req.xml localhost:9999/cgi-bin/calcserver.cgi
    

    2 arm-linux 버전의 gsoap 컴파일


    2.1 gsoap 소스 다운로드


    http://liquidtelecom.dl.sourceforge.net/project/gsoap2/gSOAP/gsoap_2.8.33.zip

    2.2 컴파일 환경 구성

  • linaro toolchain을 다운로드하여 디렉터리/usr/local/linaro-multilib-2014.06-gcc4.9로 압축 해제
  • 설정PATH환경 변수.export PATH=/usr/local/linaro-multilib-2014.06-gcc4.9:$PATH

  • 2.3 config&make


    2.3.1 makefile 생성

    gsoap-2.8$ ./configure --host=arm-linux-gnueabihf --prefix=/usr/local/arm-linux
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for arm-linux-gnueabihf-strip... arm-linux-gnueabihf-strip
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... gawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking build system type... x86_64-unknown-linux-gnu
    checking host system type... arm-unknown-linux-gnueabihf
    checking whether make sets $(MAKE)... (cached) yes
    checking for arm-linux-gnueabihf-g++... arm-linux-gnueabihf-g++
    checking whether the C++ compiler works... yes
    checking for C++ compiler default output file name... a.out
    checking for suffix of executables... 
    checking whether we are cross compiling... yes
    ...
    
  • --host=arm-linux-gnueabihf - 컴파일된 라이브러리가 arm linux에서 실행되고 있음을 나타낸다. 이것도 gcc컴파일러의 접두사이다.
  • --prefix=/usr/local/arm-linux - 컴파일된 라이브러리의 설치 경로를 나타낸다
  • 2.3.2 수동 생성 wsdl.h 파일

    gsoap-2.8$ cd gsoap/wsdl
    gsoap-2.8/gsoap/wsdl$ ../../target-amd64/bin/soapcpp2 -SC -pwsdl -I. -I../../gsoap/import ./wsdl.h
    
    **  The gSOAP code generator for C and C++, soapcpp2 release 2.8.33
    **  Copyright (C) 2000-2016, Robert van Engelen, Genivia Inc.
    **  All Rights Reserved. This product is provided "as is", without any warranty.
    **  The soapcpp2 tool and its generated software are released under the GPL.
    **  ----------------------------------------------------------------------------
    **  A commercial use license is available from Genivia Inc., [email protected]
    **  ----------------------------------------------------------------------------
    
    soapcpp2: using both options -C and -S omits client/server code
    Saving wsdlStub.h annotated copy of the source interface file
    Saving wsdlH.h serialization functions to #include in projects
    Saving xmime.nsmap namespace mapping table
    Saving wsdlC.cpp serialization functions
    
    Compilation successful 
    
    ../../target-amd64/bin/soapcpp2 이것은 당신의host기계가 실행할 수 있는 soapcpp2입니다. 만약 이 단계를 하지 않는다면 컴파일 과정에서 다음과 같은 오류가 발생할 것입니다. 컴파일할 때 생성된 soapcpp2는armlinux에서만 실행될 수 있기 때문입니다.
    make[4]: Entering directory `/home/meng/git/gsoap-2.8/gsoap/wsdl'
    ../../gsoap/src/soapcpp2 -SC -pwsdl -I. -I../../gsoap/import ./wsdl.h
    /bin/bash: ../../gsoap/src/soapcpp2: cannot execute binary file: Exec format error
    make[4]: *** [wsdlC.cpp] Error 126
    
    

    2.3.3 코드 수정


    수정config.h 파일, 마지막 줄의 #define malloc rpl_malloc을 삭제하지 않으면 컴파일 오류가 발생합니다.'

    2.3.4 makefile 수정

    gsoap/wsdl 디렉터리에 있는 Makefile를 수정하고 다음 두 줄을 삭제합니다. (wsdl2h는 다른 라이브러리에 의존하고 우리도arm버전의 wsdl2h 프로그램이 필요하지 않기 때문입니다.)
    wsdl2h$(EXEEXT): $(wsdl2h_OBJECTS) $(wsdl2h_DEPENDENCIES) $(EXTRA_wsdl2h_DEPENDENCIES) 
        #@rm -f wsdl2h$(EXEEXT)
        #$(AM_V_CXXLD)$(wsdl2h_LINK) $(wsdl2h_OBJECTS) $(wsdl2h_LDADD) $(LIBS)
    

    2.3.5 컴파일링, 설치

    gsoap-2.8$ make
    gsoap-2.8$ make install
    

    디렉터리 /usr/local/arm-linux 에서 컴파일된 gsoap 라이브러리입니다. 주:armlinux 버전을 컴파일하지 않았습니다. wadl2h

    2.4arm-linux 버전calcserver를 컴파일합니다.cgi

  • cgi버전의calcserver를 컴파일합니다.cgi
  • calcserver$ arm-linux-gnueabihf-g++ -o calcserver.cgi calcserver.cpp soapC.cpp soapcalcService.cpp -lgsoap++ -DWITH_FASTCGI -L/usr/local/arm-linux/lib -I/usr/local/arm-linux/include
    
  • fastcgi버전을 지원하는calcserver를 컴파일합니다.cgi[5]
  • calcserver$ arm-linux-gnueabihf-g++ -o calcserver.cgi calcserver.cpp soapC.cpp soapcalcService.cpp /gsoap-source-path/gsoap/stdsoap2.cpp -DWITH_FASTCGI  -I/usr/local/arm-linux/include -I/fcgi-lib-path/fcgi/include -L/fcgi-lib-path/fcgi/usr/lib -lfcgi
    
  • fcgi-lib-path-이거armlinux판을 가리키는 fcgi 라이브러리
  • gsoap-source-path-이 gsoap을 가리키는 원본 경로'
  • 우리는 stdsoap2.cpp 이 파일을 컴파일하고 링크하지 않습니다libsoap++.a
  • 정의WITH_FASTCGI 매크로
  • 2.5 구성 lighttpd


    만약 cgi버전을 컴파일했다면, 직접 컴파일된calcserver를 사용하십시오.cgi는 cig-bin 디렉터리에 놓으면 됩니다.fastcgi 버전의 경우 lighttpd 프로필을 수정하여 다음과 같은 내용을 추가해야 합니다(전제 lighttpd가 fastcgi를 지원하도록 구성되어 있음).
    fastcgi.server = (
      "calcserver.cgi" =>
      (( "socket" => "/tmp/fcgi.socket",
         "check-local" => "disable",
         "bin-path" => "/webSvr/web/cgi-bin/calcserver.cgi",
         "max-procs" => 1,
      ))
    )
    

    3 참조 문서

  • Apache Tutorial: Dynamic Content with CGI
  • Getting Started with gSOAP
  • gSoap missing stdsoap2.cpp, undefined reference to `soap_peek_element'
  • Curl 웹serivce 디버깅 호출 구현
  • 19.32 FastCGI Support - genivia.com
  • linux 장치의 Onvif 구현 4:gsoap 2.8.15 - blog.csdn
  • 좋은 웹페이지 즐겨찾기