gsoap快速webservice服务开发
(C代码)
1、编写头文件test.h
//gsoap ns service name: test
//gsoap ns service protocol: SOAP
//gsoap ns service style: rpc
//gsoap ns service namespace: http://192.168.1.7:8888/test.wsdl
//gsoap ns service location: http://192.168.1.7:8888
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:test
int ns__add(int a,int b,int *r);
#include "soapH.h"
#include "test.nsmap"
int http_get(struct soap *soap);
int main(int argc, char **argv)
{
int m,s; // 主、从套接字
struct soap soap;
soap_init(&soap);
soap.fget = http_get;<span style="white-space:pre"> </span>//用于http请求wsdl文件
soap_set_namespaces(&soap,namespaces);
if(argc < 2)
exit(-1);
m = soap_bind(&soap,NULL,atoi(argv[1]),100);
if(!soap_valid_socket(m))
{
soap_print_fault(&soap,stderr);
exit(-1);
}
fprintf(stderr , "Socket connection successful: master socket = %d\n",m);
for(;;)
{
s = soap_accept(&soap);
fprintf(stderr,"New socket connect: slave socket = %d\n",s);
if(!soap_valid_socket(s))
{
soap_print_fault(&soap,stderr);
exit(-1);
}
soap_serve(&soap);
soap_end(&soap);
}
return 0;
}
int ns__add(struct soap *soap,int n1,int n2,int *result)
{
*result = n1 + n2;
return SOAP_OK;
}
int http_get(struct soap *soap)
{
FILE *fd = fopen("test.wsdl","rb");
if(!fd)
return 404;
soap->http_content = "text/xml";
soap_response(soap,SOAP_FILE);
for(;;)
{
size_t r = fread(soap->tmpbuf,1,sizeof(soap->tmpbuf),fd);
if(!r)
break;
if(soap_send_raw(soap,soap->tmpbuf,r))
break;
}
fclose(fd);
soap_end_send(soap);
return SOAP_OK;
}
3、Makefile
GSOAP_ROOT=/usr/local/gSOAP
WSNAME=test
CC=g++ -g -DWITH_NONAMESPACES
INCLUDE=-I $(GSOAP_ROOT)/include
SERVER_OBJS=soapC.o soapServer.o stdsoap2.o
ALL_OBJS=${WSNAME}server.o soapC.o soapServer.o
all:server
${WSNAME}.wsdl:${WSNAME}.h
$(GSOAP_ROOT)/bin/soapcpp2 -c $(GSOAP_ROOT)/import ${WSNAME}.h
stdsoap2.o:$(GSOAP_ROOT)/src/stdsoap2.c
$(CC) -c $? $(INCLUDE)
$(ALL_OBJS):%.o:%.c
$(CC) -c $? $(INCLUDE)
server:Makefile ${WSNAME}.wsdl ${WSNAME}server.o $(SERVER_OBJS)
$(CC) $(WSNAME)server.o $(SERVER_OBJS) -o ${WSNAME}server
clean:
rm -f *.o *.xml *.a *.wsdl *.nsmap \
$(WSNAME0)H.h $(WSNAME0)C.c $(WSNAME0)Server.c $(WSNAME0)Client.c \
$(WSNAME0)Stub.* $(WSNAME)$(WSNAME)Proxy.* $(WSNAME)$(WSNAME)Object.* \
$(WSNAME0)ServerLib.c $(WSNAME0)ClientLib.c $(WSNAME)server ns.xsd $(WSNAME)test \
soap*.* stdsoap*.*
#./testserver 8888 &
5、浏览器输入:http://192.168.1.7:8888 可看到wsdl文件内容,C#可以直接使用该链接添加web服务引用。
PS:不用C++的原因是发现当前版本(2.8.23),C++的服务端代码只能直接调取服务方法,无法用http方式获取wsdl文件,且一旦有http请求过来,会导致服务器崩溃。
PS的PS:其实就两句代码搞定(当然,前提是正确安装了gsoap,请移步安装gSOAP)
1、生成 通信层相关代码
#soapcpp2 -c -S -L /usr/local/gSOAP/import test.h
解释一下,-c 是生成C语言版本的代码,-S是仅生成服务端代码,-L是不生成soapClientLib或soapServerLib
2、编译可执行文件
g++ -g -DWITH_NONAMESPACES -o testserver testserver.c soapC.c soapServer.c /usr/local/gSOAP/src/stdsoap2.c -I /usr/local/gSOAP/include/#
可以看到就引用了三个gsoap文件,soapC.c soapServer.c stdsoap2.c 以及相应的头文件。