SOAP with C/C++ & PHP

C/C++与PHP SOAP接口实现
本文介绍如何使用gSOAP库创建C/C++客户端与PHP服务器之间的SOAP接口。通过具体示例展示了从生成必要的代码到实现加密服务的完整过程。

SOAP with C/C++ & PHP

For my work, I need to create a client/server interface. The client must be programmed with C/C++ and the server with PHP.

After a quick look on the web, I found two projects of a SOAP C++ library which match with my requirement :
- Easysoap - http://easysoap.sourceforge.net/
- Axis - http://ws.apache.org/axis/index.html
- Gsoap - http://www.cs.fsu.edu/~engelen/soap.html

The main problem with the first one is the lake of maintenance of the project. Maybe there is no bug in it but the "last modification 12-April-2002" scared me a bit.
Despite the excellent reputation of apache's projects, I won't Axis because the requierement of having a webserver (apache) already installed on his computer (which is my case but not everybody).

For PHP, there is no standard version for PHP 4. There is one by default in PHP 5, but I am not ready to switch to this version (I know that I will have the envy to adapt my development with the object model that PHP 5 proposes).
One of the reference for PHP4 is :
- Nusoap - http://dietrich.ganx4.com/nusoap/index.php which has been developed using PHP (one file of 224 ko ...)

[Suite:]

The PHP server
It is quite simple.
Download the nusoap program.

Create a php file located on your webserver :

<?php
function encrypt($myString) {
return md5("salt".md5($myString));
}

require('nusoap.php');

$server = new soap_server();

$server->configureWSDL('security', 'urn:secure'); // Name of the server & the namespace in order to create the wsdl doc

$server->register("encrypt", // method name
array('symbol' => 'xsd:string'), // input parameters
array('return' => 'xsd:string'), // output parameters
'urn:secure', // namespace
'urn:secure#encrypt'); // SOAP action

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA)
? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

I declare the datatype of each variable to avoid mistake about datatypes.

The C client

/path/to/gsoap-linux-2.7/wsdl2h -c -o encrypt.h http://localhost/soap.php?wsdl

The -c option is used to force the generation in C.
This command creates the include thanks to the wsdl declaration.
In this file, we can find what we declared on the server (C++ style) :

int ns1__encrypt(
std::string symbol,
std::string &return_ // < response parameter
);

If you use C++, you will need the stlvector.h file in your current directory.

/path/to/gsoap-linux-2.7/soapcpp2 -c encrypt.h

Will generate the skeletons, xml sample of the flux ...

List of the files :

soapStub.h header file with data type annotations
soapH.h header file of soapC.cpp
soapC.c SOAP/XML (de)serializers for C/C++ data types
soapClient.c proxy stub routines for remote method calls
soapServer.c skeleton routines for service implementation
securityBinding.nsmap a namespace mapping table for the client application
securityBinding.encrypt.req.xml xml sample of the request
securityBinding.encrypt.res.xml xml sample of the response
encrypt.h the header file declarations
soapsecurityBindingObject.hProxy class (ie C++) for the service
soapsecurityBindingProxy.h Proxy class (ie C++) for the client
soapClientLib.c 
soapServerLib.c 

Create a encryptclient.c file :

#include "soapH.h" // obtain the generated stub 
#include "securityBinding.nsmap" // obtain the namespace mapping table
#include "stdio.h"

int main() {
struct soap soap; // gSOAP runtime environment
soap_init(&soap); // initialize runtime environment (only once)
char *myVar="sandra";
char *result;
if (soap_call_ns1__encrypt(&soap, NULL, NULL, myVar , &result) == SOAP_OK)
printf("Key encrypted = %s ",result);
else
soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
soap_end(&soap); // remove deserialized data and clean up
soap_done(&soap); // detach the gSOAP environment
return (0);
}

To compile this wonderful application :
gcc -g -I/path/to/gsoap-linux-2.7 -Wall -o encryptclient encryptclient.c soapC.c soapClient.c /path/togsoap-linux-2.7/stdsoap2.c

The processus for a C++ application is almost the same except that you don't have to use the -c parameter when saopcpp2 and wsdl2h are called.
Generated files will have an other extension (cpp instead of c) and include an proxy (basically a wrapper to use the soap web service).

There is the C++ solution without the proxy :

#include "soapH.h" // obtain the generated stub
#include "securityBinding.nsmap" // obtain the namespace mapping table
#include <iostream>
#include <string>

using namespace std;
int main() {
struct soap soap; // gSOAP runtime environment
soap_init(&soap); // initialize runtime environment (only once)
std::string myVar="sandra";
std::string result;
if (soap_call_ns1__encrypt(&soap, NULL, NULL, myVar , result) == SOAP_OK)
cout << "Key encrypted = " << result;
else
soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
soap_destroy(&soap); // delete deserialized class instances (for C++ only)
soap_end(&soap); // remove deserialized data and clean up
soap_done(&soap); // detach the gSOAP environment
}

With the proxy (smaller & cleaner isn't it ?) :

#include "soapsecurityBindingProxy.h" /* get the gSOAP-generated proxy */
#include "securityBinding.nsmap" /* get service namespace bindings */
int main() {
securityBinding sec;
string result;
if (sec.ns1__encrypt(string("sandra"), result) == SOAP_OK)
cout << "Key encrypted = " << result;
else
soap_print_fault(sec.soap, stderr);
}

For both sources, the compilation command is :

g++ -I/path/to/license/gsoap-linux-2.7 -Wall -o encryptclient encryptclient.cpp soapC.cpp soapClient.cpp /path/to/gsoap-linux-2.7/stdsoap2.cpp

If you want to use SSL (without prior authentication), just add this

if (soap_ssl_client_context(&soap,SOAP_SSL_NO_AUTHENTICATION,NULL,NULL,NULL,NULL,NULL)) {
soap_print_fault(&soap, stderr);
exit(1);
}

and change the URL (https instead of http) in soapClient.{c/cpp]

URL = "https://localhost/soap.php";

And add :

-DWITH_OPENSSL -lssl -lcrypto

to gcc/g++.

Bonus - The client in Python with SOAPpy - http://pywebsvcs.sourceforge.net/ :

#!/usr/bin/python
import SOAPpy
try:
server = SOAPpy.SOAPProxy("http://localhost:80/soap.php")
print server.encrypt("sandra")
except Exception, e:
print """Error : %s """% e
Sources :
Tutorial - Nusoap with PHP4 : http://codewalkers.com/tutorials/74/4.html
gSOAP User Guide : http://www.cs.fsu.edu/~engelen/soapdoc2.html
Creating a C/C++ client for a WebSphere Web service using WebSphere Studio Application Developer, gSOAP, and Dev-C++ : http://www-900.ibm.com/developerWorks/cn/wsdd/library/techarticles/0301_lin/lin_eng.shtm 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值