WSO2 WSF/CPP 网络服务开发例子1--HELLO

一、根据需求编写WSDL文档

定义一个服务叫做hello,提供三个操作(greet1、greet2、greet3),这三个操作均接受一个输入字符串,并在该字符串后追加自己的名字后返回给客户端。WSDL文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions targetNamespace="axis2.services.hello"

xmlns:apachesoap="http://xml.apache.org/xml-soap"

xmlns:impl="axis2.services.hello"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<wsdl:types>

<schema elementFormDefault="qualified"

targetNamespace="axis2.services.hello"

xmlns="http://www.w3.org/2001/XMLSchema"

xmlns:apachesoap="http://xml.apache.org/xml-soap"

xmlns:impl="axis2.services.hello"

xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

<element name="greetRequest">

<complexType>

<sequence>

<element name="greetInput" type="xsd:string" />

</sequence>

</complexType>

</element>

<element name="greetResponse">

<complexType>

<sequence>

<element name="greetReturn" type="xsd:string" />

</sequence>

</complexType>

</element>

</schema>

</wsdl:types>

<wsdl:message name="greetResponse1">

<wsdl:part element="impl:greetResponse" name="parameters" />

</wsdl:message>

<wsdl:message name="greetRequest1">

<wsdl:part element="impl:greetRequest" name="parameters" />

</wsdl:message>

<wsdl:message name="greetResponse2">

<wsdl:part element="impl:greetResponse" name="parameters" />

</wsdl:message>

<wsdl:message name="greetRequest2">

<wsdl:part element="impl:greetRequest" name="parameters" />

</wsdl:message>

<wsdl:message name="greetResponse3">

<wsdl:part element="impl:greetResponse" name="parameters" />

</wsdl:message>

<wsdl:message name="greetRequest3">

<wsdl:part element="impl:greetRequest" name="parameters" />

</wsdl:message>

<wsdl:portType name="hello">

<wsdl:operation name="greet1">

<wsdl:input message="impl:greetRequest1" name="greetRequest1" />

<wsdl:output message="impl:greetResponse1" name="greetResponse1" />

</wsdl:operation>

<wsdl:operation name="greet2">

<wsdl:input message="impl:greetRequest2" name="greetRequest2" />

<wsdl:output message="impl:greetResponse2" name="greetResponse2" />

</wsdl:operation>

<wsdl:operation name="greet3">

<wsdl:input message="impl:greetRequest3" name="greetRequest3" />

<wsdl:output message="impl:greetResponse3" name="greetResponse3" />

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="HelloSoapBinding" type="impl:hello">

<wsdlsoap:binding style="document"

transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:operation name="greet1">

<wsdlsoap:operation soapAction="hello#greet1" />

<wsdl:input name="greetRequest1">

<wsdlsoap:body use="literal" />

</wsdl:input>

<wsdl:output name="greetResponse1">

<wsdlsoap:body use="literal" />

</wsdl:output>

</wsdl:operation>

<wsdl:operation name="greet2">

<wsdlsoap:operation soapAction="hello#greet2" />

<wsdl:input name="greetRequest2">

<wsdlsoap:body use="literal" />

</wsdl:input>

<wsdl:output name="greetResponse2">

<wsdlsoap:body use="literal" />

</wsdl:output>

</wsdl:operation>

<wsdl:operation name="greet3">

<wsdlsoap:operation soapAction="hello#greet3" />

<wsdl:input name="greetRequest3">

<wsdlsoap:body use="literal" />

</wsdl:input>

<wsdl:output name="greetResponse3">

<wsdlsoap:body use="literal" />

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="hello">

<wsdl:port binding="impl:HelloSoapBinding" name="hello">

<wsdlsoap:address location="http://192.168.34.41:9090/axis2/services/hello" />

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

二、使用代码生成工具生成服务端框架

wsf/c++提供了代码生成工具,该工具根据输入的wsdl文件生成网络服务服务端代码或者客户端代码。

生成服务端框架:

WSDL2CPP.sh -uri hello.wsdl -ss -sd -d adb -u

生成客户端存根

WSDL2CPP.sh -uri hello.wsdl -d adb -u

下图为生成后的文件列表:

三、在工具生成的代码上实现功能

1、实现服务端业务逻辑代码并发布

生成的服务端代码主要包含在4个类中,分别对应4个头文件:GreetRequest.h GreetResponse.h hello.h helloSkeleton.h。

类GreetRequest封装了WSDL中定义的请求消息;类GreetResponse封装了WSDL中定义的回复消息;类hello派生自ServiceSkeleton(在介绍WSF/CPP中有介绍),实现了服务框架的虚函数接口,比如在invoke函数中已经实现了根据请求消息中的信息,分发请求到具体的操作中;类helloSkeleton封装了WSDL中定义的所有操作,这是我们 填写业务逻辑代码的地方。

对于当前这个简单的例子来说,我们只需要在类helloSkeleton提供的对应操作的几个函数里实现业务逻辑代码即可,部分代码如下:

/**

* Auto generated function definition signature

* for "greet1|axis2.services.hello" operation.

*

* @param _greetRequest of the hello_services_axis2::GreetRequest

*

* @return hello_services_axis2::GreetResponse*

*/

hello_services_axis2::GreetResponse* helloSkeleton::greet1(

wso2wsf::MessageContext *outCtx,

hello_services_axis2::GreetRequest* _greetRequest)

{

/* TODO fill this with the necessary business logic */

GreetResponse* _greetResponse = new GreetResponse();

if (_greetRequest->isGreetInputNil()) {

_greetResponse->setGreetReturn("greet1 recive nothine!");

} else {

_greetResponse->setGreetReturn(

_greetRequest->getGreetInput() + " greet1.");

}

return _greetResponse;

}

由于所有操作的业务逻辑都一样,所以这里就不帖出另外两个操作函数的业务逻辑代码,完整代码请看附件。

接下来我们需要编译这个工程,MS Window平台这里就不介绍了,因为代码生成工具已经生成了对应的工程文件,下面帖出在linux环境下的makefile文件。

首先是rules.mk:

CPP = g++ -g -O2 -msse3 -Wall -fPIC -DPIC -D_REENTRANT -DG_BYTE_ORDER=G_LITTLE_ENDIAN -DLINUX

MAKESO = g++ -g -O2 -msse3 -Wall -shared -fPIC -DPIC -D_REENTRANT -DLINUX

CPPLINK    = $(CPP) $(CPPFLAG)

AR  = ar

ARFLAG = -rc

CP  = cp -f

RM  = rm -f

MV  = mv

#### IFX & MQ INSTALL DIR ####

#### FOR SYSTEM ####

SYSLIB = -lpthread

TOPSRC=`pwd`

接着是Makefile:

.SUFFIXES: .o .cpp

include rules.mk

SRCS=$(wildcard *.cpp)

OBJS=$(patsubst %.cpp,%.o,$(SRCS))

INCLS=-I/opt/wso2/wsf_cpp/include \

-I/opt/wso2/wsf_cpp/include/axis2-1.6.0 \

-I/opt/wso2/wsf_cpp/include/axis2-1.6.0/platforms \

-I../include

LIBS =-L/opt/wso2/wsf_cpp/lib \

-laxutil \

-laxis2_axiom \

-laxis2_engine \

-laxis2_parser \

-lpthread \

-laxis2_http_sender \

-laxis2_http_receiver \

-lguththila \

-lwso2_wsf

TARGET =   libhello.so

$(TARGET): $(OBJS)

$(MAKESO) -o $@ $(OBJS) $(LIBS)

.cpp.o:

$(CPP) $(INCLS) -c $<

all:   $(TARGET)

clean:

rm -f $(OBJS) $(TARGET)

现在,只要需要将服务发布出去,我使用的是WSF CPP发布包中包含的Axis2 Server作为服务,在前面介绍WSF CPP的文章中有较详细的介绍,这里简单称述如下几个步骤:

A.在路径/opt/wso2/wsf_cpp/services中新建目录hello。

B.拷贝文件libhello.so hello.wsdl services.xml到hello目录中。services.xml由代码生成工具生成。

C.重启Axis2 Server。

如上三步完成服务的发布,打开页面http://192.168.34.41:9090/axis2/services/ 可以看到有效服务列表,其中属于hello的部分截图如下:

打开页面http://192.168.34.41:9090/axis2/services/hello?wsdl 可以看到这个服务对应的wsdl。

2、实现客户端代码并执行

代码生成工具为客户端也生成了4个类,其中GreetRequest和GreetResponse跟服务端的一样只是封装了服务相关的消息;helloStub派生自WSF CPP提供的Stub类,封装了WSF CPP客户端API,通过构造函数完成初始化,另外为每一个Web服务操作提供了同步调用和异步调用的方法;IhelloCallback定义了异步调用Web服务操作时需要使用的回调函数接口。

生成的代码只是提供了必须的东西,并不能生成一个可执行程序,因为其中还没有main函数呢。所以接下来需要实现一个完整的客户端。

A.添加一个新文件hello.cpp到工程的src目录,并在其中编写如下代码:

#include <Environment.h>

#include "helloStub.h"

using namespace std;

using namespace wso2wsf;

using namespace hello_services_axis2;

int main(int argc, char *argv) {

Environment::initialize("hello.log", AXIS2_LOG_LEVEL_TRACE);

string endpointUri = "http://192.168.34.41:9090/axis2/services/hello";

string clientHome = AXIS2_GETENV("WSFCPP_HOME");

if (clientHome.empty()) {

cout << "Please set the WSFCPP_HOME environment variable" << endl;

}

helloStub *stub = new helloStub(clientHome, endpointUri);

GreetRequest *request = new GreetRequest("hello server");

GreetResponse *response = stub->greet1(request);

if (response)

{

cout << response->getGreetReturn() << endl;

}

delete stub;

return 0;

}

其实上面代码所示的动作基本上都是固定的,先初始化,接着实例化一个stub,然后创建一个请求消息,通过同步的方式发送请求并接收回复就结束了。

B.给客户端工程创建一个Makefile文件,由于rules.mk跟服务端的一样,这里就不再帖出详情了,Makefile文件内容如下:

.SUFFIXES: .o .cpp

include rules.mk

SRCS=$(wildcard *.cpp)

OBJS=$(patsubst %.cpp,%.o,$(SRCS))

INCLS=-I/opt/wso2/wsf_cpp/include \

-I/opt/wso2/wsf_cpp/include/axis2-1.6.0 \

-I/opt/wso2/wsf_cpp/include/axis2-1.6.0/platforms \

-I../include

LIBS =-L/opt/wso2/wsf_cpp/lib \

-laxutil \

-laxis2_axiom \

-laxis2_engine \

-laxis2_parser \

-lpthread \

-laxis2_http_sender \

-laxis2_http_receiver \

-lguththila \

-lwso2_wsf

TARGET = hello

$(TARGET): $(OBJS)

$(CPP) -o $@ $(OBJS) $(LIBS)

.cpp.o:

$(CPP) $(INCLS) -c $<

all:   $(TARGET)

clean:

rm -f $(OBJS) $(TARGET)

跟服务端所需的引用路径和库都一样,不同的只是最终生成可执行程序而不是库。

C.编译成功后,只剩下执行这个程序了,由于日志等级设置的比较低,所以输出很多,下面只提出关键的输出:

[luochong@pay-db-server src]$ ./hello

hello server greet1.

“hello server greet1.“是客户端将收到的回复打印出来的结果。

[服务端源码]

[客户端源码]

转载于:https://www.cnblogs.com/seamancode/archive/2011/07/29/wso2_wsf_cpp_hello.html

WSO2 WSF/CPP 网络服务开发例子1--HELLO相关推荐

  1. QT网络编程开发服务端

    下一篇: QT网络编程开发客户端 文章目录 基于Qt的网络编程服务端 QTcpServer 配置 listen() close() newConnection() SINGL readyRead() ...

  2. 安卓电话和网络开发全解:电话硬件检测、电话服务信息、sim信息、网络服务信息、数据连接和数据传输信息、电话状态监听

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓电话和网络开发全解,包括电话硬件检测.电话服务信息.sim信息.网络服务信息.数据连接和数据传输信息.通过phone state listener ...

  3. 《“透视”个人大数据》项目开发小记 --(二)网络服务端,邮箱验证和手机验证(C#,Java)

    现在网络的应用越来越普及,网络的构建也越来越简便,对于某些研究性项目自建网络服务端 也是可行的方案.本项目的网络服务,是用C#,基于Socket构建的,核心的工作是通过自定的BS60传输协议,实现与手 ...

  4. Go 开源说第十八期预告:基于 Reactor 模式开发网络服务——gnet

    点击蓝字 关注我们 写在前面 GoCN开源说是GoCN推出的一档分享Go开源好项目的直播栏目,通过开源说希望能够帮助到开源作者们实现以下目标: 第一是去推广他们的开源项目 第二说说背后的设计原理和理念 ...

  5. Linux网络服务-Web Service之【HTTP协议简介】(一)

    一.什么是HTTP? 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议.设计HTTP最初的目的是为了提供一种发布和接收 ...

  6. python3 socketserver模块 网络服务编程框架

    socket编程过于底层,编程虽然有套路,但是想要写出健壮的代码还是比较困难的,所以很多语言都对socket底层 API进行封装,Python的封装就是--socketserver模块.它是网络服务编 ...

  7. 用ACE的Reactor模式实现网络通讯的例子

    用ACE的Reactor模式实现网络通讯的例子,不罗嗦,直接上代码. 服务器代码: [cpp] view plain copy #include <ace/Reactor.h> #incl ...

  8. openstack第四章:neutron— 网络服务

    第四篇neutron- 网络服务 一.neutron 介绍:   Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是 ...

  9. 地图结合资料 提供全新网络服务

    引用自:http://cgi.blog.yam.com/trackback/327858 耶鲁大学计算机系教授David Gelernter 1991年提议,利用软件将实体世界虚拟在计算机屏幕上,从交 ...

最新文章

  1. JVM 与 Linux 的内存关系详解
  2. Referenced file contains errors (http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_4.xsd).
  3. version control(版本控制)
  4. Java 垃圾回收算法之G1
  5. SpringMVC之源码分析--ThemeResolver(三)
  6. 有关C++11标准的一些粗浅认识
  7. 使用 onpropertychange 和 oninput 检测 input、textarea输入改变
  8. outlook查看html,怎样察看IE/Outlook中HTML页面的源文件
  9. Endnote教程:如何快速搞定论文里的参考文献格式?
  10. 2021-2025年中国智能储藏加热器行业市场供需与战略研究报告
  11. Xposed框架Xposed安装器|Xposed for Android 5.0/5.1/6.0|详细安装教程
  12. 华为路由器Serial接口及串口无法实现ACL访问控制解析
  13. 惠普HP LaserJet Pro M15a 打印机驱动
  14. 二叉树——二叉树的深度
  15. php实现猫眼电影院选座思路,高仿猫眼电影选座(选票)模块
  16. 智能合约(Smart contract)
  17. 瞬间让你效率提高一倍的高效学习方法
  18. 郑大计算机专业英语第11章在线测试,郑大远程教育大学英语I 1-10章测试题
  19. 如何购买大容量的邮箱?哪里可以申请注册大量邮箱?
  20. 光学三维测量技术及应用

热门文章

  1. 每一个企业的供应商都有供应商
  2. 响应函数sys_xxx
  3. 我的宽带是100兆,为什么到户只有30-50兆,我应该换成什么型号的路由器?
  4. 阿里为什么偏向全资收购(高德、优酷、饿了么等)?腾讯只是投资?
  5. docker RUN、CMD 和 ENTRYPOINT
  6. 解决VMWare虚拟机IP变成127.0.0.1和选择固定IP段
  7. alwayson高可用组_AlwaysOn可用性组–简化工作的好奇心–第3部分
  8. 数学之美 与 浪潮之巅
  9. 通过读取配置文件,启动mongodb
  10. 1619. [HEOI2012]采花