[gSoap]使用RESTful架构搭建简单跨平台Webservice

版权声明:本文为博主原创文章,转载请注明 http://blog.csdn.net/u012741077 https://blog.csdn.net/u012741077/article/details/53073822

简介

  原先是直接使用的Socket来进行网络编程,但遇到高并发我就难以招架了,与是在网上找了一下,发现了开源的gSoap跨平台库,于是就开始尝试使用起来。
  官方主页:https://www.genivia.com/products.html
  说明文档:https://www.genivia.com/doc/soapdoc2.html
  源码下载:https://sourceforge.net/projects/gsoap2/

  由于现在所要做的程序只需要短连接,所以就只用到了gSoap所支持的RESTful功能。
  本文只讲述在Windows环境下的编程,linux下经测试流程是一样的。

开发步骤

创建Webservice相关声明头文件

该文件需要按特定格式书写,并且注释有特定的意义,详细可看文档。我说创建的最简化声明文件“Webservice.h”文件如下,名字可随意,不影响项目。

//gsoap ns service name: GameWebservice 
//gsoap ns service location: http://localhost
//gsoap ns service namespace: urn:GameWebservice

int ns__test(void*);

“ns_test”函数是SOAP远程调用函数,因为使用的是RESTful,所以不用关心,但必须声明一个。

使用“soapcpp2”创建项目源文件

“soapcpp2.exe”在源码目录下“gsoap/bin/win32”目录中,linux下的则需要自己重新编译,文档中也有说明。
使用如下命令创建。

soapcpp2.exe -0 -S -L -r -w -x GameWebService.h

结果如下图:
这里写图片描述

一共生成了6个文件,有5个是必要的,还有一个是生成的说明文件,可以不要。

  • soapStub.h
  • soapServer.cpp
  • soapH.h
  • soapC.cpp
  • GameWebservice.nsmap

创建c++工程,并添加相关文件

为了简单,我使用vs创建一个c++控制台工程。然后将上面所说的5个文件添加到工程中。
添加gSoap源文件,在“gsoap”目录下。

  • stdsoap2.h
  • stdsoap2.cpp

为了方便使用RESTful,将“gsoap\plugin”中的如下文件添加到工程中。

  • httppost.h 与 httppost.c
  • httpget.h 与 httpget.c

由于需要使用到socket,所以要在vs的附加依赖项中添加“ws2_32.lib;”。

编写main

# include <iostream>
using namespace std;

//gsoap
# include "soapH.h"
# include "httpget.h"
# include "httppost.h"
# include "GameWebservice.nsmap"//重要!!该文件不要重复包含,会产生重复定义

int HttpGetHandler(struct soap* soap);
int HttpPostHandler(struct soap* soap);
int CheckAuthorization(soap * soap);

//Post根据mime分配回调
struct http_post_handlers ghttpPostHndlers[] =
{
    { "POST", HttpPostHandler },
    { 0 }
};

//用于简单认证的账户和密码
#define USERID "admin"
#define PASSWORD "123456"

//设置
#define LISTENPORT 8080
#define LISTENMAX 100

int main()
{
    struct soap soap;
    soap_init(&soap);//初始化

    //注册get请求回调函数
    soap_register_plugin_arg(&soap, http_get, (void*)HttpGetHandler);

    //注册post请求回调函数
    soap_register_plugin_arg(&soap, http_post, (void*)ghttpPostHndlers);

    //用于简单认证,设置帐号密码,选加
    soap.userid = USERID;
    soap.passwd = PASSWORD;
    //

    SOAP_SOCKET ssock = soap_bind(&soap, 0, LISTENPORT, LISTENMAX);

    fprintf(stderr, "Start accept client !\n");
    while (true)
    {
        //监听客户端连接
        SOAP_SOCKET ssockclient = soap_accept(&soap);
        fprintf(stderr, "Client Connect !\n");
        //处理连接
        soap_serve(&soap);//运行soap
    }

    //销毁服务端
    soap_destroy(&soap);
    soap_end(&soap);
    soap_done(&soap);

    return 0;
}

//简单认证
int CheckAuthorization(soap * soap)
{
    if (!soap->userid || !soap->passwd ||
        strcmp(soap->userid, USERID) ||
        strcmp(soap->passwd, PASSWORD))
    {
        //认证失败 401
        return 401;
    }

    return 0;
}

int HttpGetHandler(struct soap* soap)
{
    //用于简单认证,选加
    if (CheckAuthorization(soap))
    {//认证失败
        return 401;
    }
    //
    fprintf(stderr, "HttpGetHandler!\n");

    //返回一个html
    soap_response(soap, SOAP_HTML);
    soap_send(soap, "<html>HttpGetHandler</html>");
    soap_end_send(soap);
    return SOAP_OK;
}

int HttpPostHandler(struct soap* soap)
{
    //用于简单认证,选加
    if (CheckAuthorization(soap))
    {//认证失败
        return 401;
    }
    //
    fprintf(stderr, "HttpPostHandler!\n");

    //返回一个html
    soap_response(soap, SOAP_HTML);
    soap_send(soap, "<html>HttpPostHandler</html>");
    soap_end_send(soap);
    return SOAP_OK;
}

//RESTful不需要使用此函数,但需要实现它。
int ns__test(struct soap* soap)
{
    return SOAP_NO_METHOD;
}

效果如下图:
这里写图片描述
这里写图片描述

使用gSoap可以很容易的搭建起Webservice,也可以很容易的在多个平台上使用。

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012741077/article/details/53073822