gsoap 远程调用举例

14 篇文章 0 订阅
5 篇文章 0 订阅

gsoap 远程调用举例

gsoap生成Web Service框架代码。这里通过gsoap官网**Example XML SOAP server ©Example XML SOAP client ©**例子来实现sgoap生成框架,并实现远程调用。

gsoap官网例程:https://www.genivia.com/dev.html#server-c

img

1、SOAP服务器

将gsoap安装路径下的importcustom文件夹,stdsoap2.hstdsoap2.h拷贝到需要生成文件的路径中。

利用wsdl2h工具和wsdl文档来生成.h服务接口。然后通过soapcpp2工具和.h文件生成底层代码和接口。

$ wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
$ soapcpp2 -S -L -x calc.h

最终生成服务器代码。这里需要用到的文件主要有soapC.c soapServer.c stdsoap2.c calcserver.c stdsoap2.h soapStub.h soapH.hcalcserver.c是我手动创建的,用来实现wsdl文档中的接口和主函数。
在这里插入图片描述
calcserver.c文件主要内容如下,代码来自gsoap官网案例。代码稍微有点问题,明明是C的例子,里面却出现了C++代码,这里直接将C++代码全部注释掉,不适用pow功能。

#include "calc.nsmap" // XML namespace mapping table (only needed once at the global level)
#include "soapH.h"    // server stubs, serializers, etc.

int main()
{
  struct soap *soap = soap_new1(SOAP_XML_INDENT);
  soap_set_namespaces(&soap, namespaces);
  if (!soap_valid_socket(soap_bind(soap, NULL, 8080, 10))) // port 8080 and small BACKLOG queue for iterative servers
    exit(EXIT_FAILURE);
    /* 阻塞在soap_accept处,当有远程调用产生时,接收远程调用并进行相应的处理。 */
  while (soap_valid_socket(soap_accept(soap)))
  {
      printf("accept ok\r\n");
    if (soap_serve(soap) != SOAP_OK)
      break;
    soap_destroy(soap); // delete deserialized C++ instances
    soap_end(soap);     // delete other managed data
  }
  soap_print_fault(soap, stderr);
  soap_free(soap); // free the soap struct context data
}

/* 以下是关于wsdl接口的实现。当客户端对服务器进行远程调用时,将会调用以下对应的函数。 */
int ns2__add(struct soap *soap, double a, double b, double *result)
{
    printf("ns2__add called\r\n");
    /* 这里把加法改成乘法,证明我们的调用没有问题。 */
  *result = a * b;
  return SOAP_OK;
}
int ns2__sub(struct soap *soap, double a, double b, double *result)
{
  *result = a - b;
  return SOAP_OK;
}
int ns2__mul(struct soap *soap, double a, double b, double *result)
{
  *result = a * b;
  return SOAP_OK;
}
int ns2__div(struct soap *soap, double a, double b, double *result)
{
  if (b == 0.0)
  {
    char *msg = (char*)soap_malloc(soap, 1024);
    snprintf(msg, 1024, "Trying to divide %f by zero", a);
    return soap_sender_fault(soap, msg, NULL);
  }
  *result = a / b;
  return SOAP_OK;
}
int ns2__pow(struct soap *soap, 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(soap, 1024);
//     snprintf(msg, 1024, "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
//     return soap_sender_fault(soap, "Power function domain error", s);
//   }
  return SOAP_OK;
}

完成calcserver.c后,编译server并运行。我这里是通过wsl编译运行的。

$ gcc soapC.c soapServer.c stdsoap2.c calcserver.c -o calcserver
$ ./calcserver

这时服务器的ip使我们的本机IP:192.168.x.x,然后端口号是上面设置的8080。服务器已经搭建完成了,接下来进行client端开发,来访问我们的服务器。


2、SOAP客户端

Client操作流程和Server类似。同样的操作步骤,修改命令参数即可。这里将Client代码路径修改一下,不要和Server放在同一路径下,因为生成的soapStub.h有略微差异,后面不方便同时修改客户端服务端代码。

根据gsoap官网的教程,生成代码。操作如下:

$ wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
$ soapcpp2 -CL -x calc.h

最终生成客户端代码。这里需要用到的文件主要有soapC.c soapClient.c stdsoap2.c calcclient.c stdsoap2.h soapStub.h soapH.hcalcClient.c是我手动创建的,用来实现main函数对Server进行访问调用。
在这里插入图片描述
calcserver.c文件主要内容如下,代码来自gsoap官网案例。这里对ns2__add进行远程调用,发送调用信息给服务器,服务器收到调用信息再调用具体实现函数。因为之前已经修改过add了,所以这里调用以后应该是乘法结构。

#include "calc.nsmap" // XML namespace mapping table (only needed once at the global level)
#include "soapH.h"    // client stubs, serializers, etc.

int main()
{
  struct soap *soap = soap_new(); // allocate and initialize a context
  double sum;
  soap->connect_timeout = 10; // connect within 10s
    soap->send_timeout = 5;     // send timeout is 5s
    soap->recv_timeout = 5;     // receive timeout is 5s
    soap->socket_flags = MSG_NOSIGNAL;
  if (soap_call_ns2__add(soap, NULL, NULL, 1.23, 4.56, &sum) == SOAP_OK)
    printf("Sum = %g\n", sum);
  else
    soap_print_fault(soap, stderr);
  soap_destroy(soap); // delete managed deserialized C++ instances
  soap_end(soap);     // delete other managed data
  soap_free(soap);    // free the soap struct context data
}

它这里的给的例子不是调用我们自己服务器的,所以需要将它调用的链接修改我们自己服务器的地址和端口号。在soapClient.c中,对相应的代码进行修改,soap_endpoint是用来控制访问地址的,这里修改成我们服务器的。

SOAP_FMAC5 int SOAP_FMAC6 soap_send_ns2__add(struct soap *soap, const char *soap_endpoint, const char *soap_action, double a, double b)
{	struct ns2__add soap_tmp_ns2__add;
	if (soap_endpoint == NULL)
		// soap_endpoint = "http://websrv.cs.fsu.edu/~engelen/calcserver.cgi";
		soap_endpoint = "192.168.x.x:8080";

完成calcclient.c后,编译client并运行。我这里是通过wsl编译运行的。

$ gcc soapC.c calcclient.c soapClient.c stdsoap2.c -o calcclient
$ ./calcclient

输出结果如下:

在这里插入图片描述


3、总结

以上就是利用gsoap工具通过wsdl文档来生成web service框架,我们只需要完成wsdl文档的接口就行了。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值