首页 > 代码库 > Ubuntu 下的webservices
Ubuntu 下的webservices
搞 了一下午:
开发服务器程序,需使用gSOAP生成服务器端代码框架。我们有两种做法:
- 编写WSDL,使用wsdl2h生成头文件,再soapcpp2生成框架代码;
- 编写头文件,使用soapcpp2生成框架代码;
这两种方式,结果是一样的,最终都有产生头文件,并生成代码。不同在于,在项目的开发中需要维护的文件不同,前者是需要维护WSDL文件,后者维护头文件。
我个人觉得第二种方式更好用,不仅仅是少了个步骤,而是WSDL的语法太难写了,有点XSD的味道。而头文件的编写,更接近于程序员的思考方式,比如定义消息结构,定义接口名称等。
gSOAP是非常智能的,它利用C/C++的注释来获取信息,所以在手工编写的头文件中,注释是用用处的,常以// gsoap 名字空间 …开头。做为学习,我准备为php blog程序wordpress写一个web service接口,名字叫wpsoap。
给出代码:
1
root@ubuntu:/home/aries/Aries/gsoap# cat add.h //gsoapopt cw //gsoap ns2 schema namespace: urn:add //gsoap ns2 schema form: unqualified //gsoap ns2 service name: add //gsoap ns2 service type: addPortType //gsoap ns2 service port:http://websrv.cs.fsu.edu/~engelen/addserver.cgi //gsoap ns2 service namespace: urn:add //gsoap ns2 service transport: http://schemas.xmlsoap.org/soap/http //gsoap ns2 service method-style: add rpc //gsoap ns2 service method-encoding: //add http://schemas.xmlsoap.org/soap/encoding/ //gsoap ns2 service method-action: add "" int ns2__add( int num1, int num2, int* sum );
注意:注释的的内容也必须加上
2 执行soapcpp2 -c add.h
3 添加一个服务端 addserver.c
root@ubuntu:/home/aries/Aries/gsoap# cat addserver.c #include "soapH.h" #include "add.nsmap" int main(int argc, char **argv) { int m, s; struct soap add_soap; soap_init(&add_soap); soap_set_namespaces(&add_soap, namespaces); if (argc < 2) { printf("usage: %s <server_port> /n", argv[0]); exit(1); } else { m = soap_bind(&add_soap, NULL, atoi(argv[1]), 100); if (m < 0) { soap_print_fault(&add_soap, stderr); exit(-1); } fprintf(stderr, "Socket connection successful: master socket = %d/n", m); for (;;) { s = soap_accept(&add_soap); if (s < 0) { soap_print_fault(&add_soap, stderr); exit(-1); } fprintf(stderr, "Socket connection successful: slave socket = %d/n", s); soap_serve(&add_soap); soap_end(&add_soap); } } return 0; } int ns2__add(struct soap *add_soap, int num1, int num2, int *sum) { *sum = num1 + num2; return 0; }
4 t添加 客服端 addclient.c
root@ubuntu:/home/aries/Aries/gsoap# cat addclient.c #include "soapStub.h" #include "add.nsmap" int add(const char *server, int num1, int num2, int *sum) { struct soap add_soap; int result = 0; soap_init(&add_soap); soap_set_namespaces(&add_soap, namespaces); soap_call_ns2__add(&add_soap, server, NULL, num1, num2, sum); printf("server is %s, num1 is %d, num2 is %d/n", server, num1, num2); if (add_soap.error) { printf("soap error: %d, %s, %s/n", add_soap.error, *soap_faultcode(&add_soap), *soap_faultstring(&add_soap)); result = add_soap.error; } soap_end(&add_soap); soap_done(&add_soap); return result; }
5 测试 上面的addtest.c
root@ubuntu:/home/aries/Aries/gsoap# cat addtest.c #include <stdio.h> #include <stdlib.h> #include <string.h> int add(const char *server, int num1, int num2, int *sum); int main(int argc, char **argv) { int result = -1; char server[128] = {0}; int num1; int num2; int sum; if (argc < 4) { printf("usage: %s <ip:port> num1 num2 /n", argv[0]); exit(1); } strcpy(server,argv[1]); num1 = atoi(argv[2]); num2 = atoi(argv[3]); result = add(server, num1, num2, &sum); if (result != 0) { printf("soap error, errcode=%d/n", result); } else { printf("%d + %d = %d/n", num1, num2, sum); } return 0; }
注意:编译的时候我们需要gsoap包里的源代码文件,把stdsoap2.c和stdsoap2.h文件拷贝到当前目录
6 makefile
root@ubuntu:/home/aries/Aries/gsoap# cat makefile GSOAP_ROOT = /mnt/hgfs/E/gsoap_2.8.17/gsoap-2.8/gsoap WSNAME = add CC = g++ -g -DWITH_NONAMESPACES INCLUDE = -I$(GSOAP_ROOT) SERVER_OBJS = soapC.o stdsoap2.o soapServer.o $(WSNAME)server.o CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o $(WSNAME)client.o $(WSNAME)test.o all: server server: $(SERVER_OBJS) $(CC) $(INCLUDE) -o $(WSNAME)server $(SERVER_OBJS) client: $(CLIENT_OBJS) $(CC) $(INCLUDE) -o $(WSNAME)test $(CLIENT_OBJS) cl: rm -f *.o *.xml *.a *.wsdl *.nsmap soapH.h $(WSNAME)Stub.* $(WSNAME)server ns.xsd $(WSNAME)test
root@ubuntu:/home/aries/Aries/gsoap# make g++ -g -DWITH_NONAMESPACES -c -o soapC.o soapC.c g++ -g -DWITH_NONAMESPACES -c -o stdsoap2.o stdsoap2.c g++ -g -DWITH_NONAMESPACES -c -o soapServer.o soapServer.c g++ -g -DWITH_NONAMESPACES -c -o addserver.o addserver.c g++ -g -DWITH_NONAMESPACES -I/mnt/hgfs/E/gsoap_2.8.17/gsoap-2.8/gsoap -o addserver soapC.o stdsoap2.o soapServer.o addserver.o
继续 make client
最后 文件如下:
add.add.req.xml addserver makefile soapH.h stdsoap2.h
add.add.res.xml addserver.c soapC.c soapServer.c stdsoap2.o
addclient.c addserver.o soapClient.c soapServerLib.c
addclient.o addtest soapClientLib.c soapServer.o
add.h addtest.c soapClient.o soapStub.h
add.nsmap addtest.o soapC.o stdsoap2.c
效果: