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">
<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/">
<wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
二、使用代码生成工具生成服务端框架
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)
{
/TODOfill 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
includerules.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
#include"helloStub.h"
usingnamespacestd;
usingnamespacewso2wsf;
usingnamespacehello_services_axis2;
intmain(intargc,char*argv) {
Environment::initialize("hello.log",AXIS2_LOG_LEVEL_TRACE);
stringendpointUri ="http://192.168.34.41:9090/axis2/services/hello";
stringclientHome = AXIS2_GETENV("WSFCPP_HOME");
if(clientHome.empty()) {
cout <<"Please set the WSFCPP_HOME environment variable"<< endl;
}
helloStubstub =new*helloStub(clientHome, endpointUri);
GreetRequestrequest =new*GreetRequest("hello server");
GreetResponse*response = stub->greet1(request);
if(response)
{
cout << response->getGreetReturn() << endl;
}
deletestub;
return0;
}
其实上面代码所示的动作基本上都是固定的,先初始化,接着实例化一个stub,然后创建一个请求消息,通过同步的方式发送请求并接收回复就结束了。
B.给客户端工程创建一个Makefile文件,由于rules.mk跟服务端的一样,这里就不再帖出详情了,Makefile文件内容如下:
.SUFFIXES: .o .cpp
includerules.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
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/29543
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!