gsoap:启用http compression(gzip)进行数据压缩传输

来源:互联网 发布:淘宝闲置物品怎么买 编辑:程序博客网 时间:2024/06/16 21:04

什么是http compression?

HTTP compression即网页压缩,简单说就是web服务器和浏览器客户端传送数据时,将网页数据/客户端响应数据在发送给对方前先进行压缩再传输的一种方式。
使用网页压缩可以减少数据传输大小,从而减少数据在网上络上传输的时间消耗,提高web服务器和客户端之间的响应速度,改善客户体验。
HTTP compression是由web服务器和浏览器之间共同遵守的协议,也就是说web服务器和浏览器都必须支持该技术才能使用这个特性,目前主流的浏览器都是支持网页压缩的,包括ie、firefox、chrome、Opera 等。常见的web服务器apache,tomcat,iis 等.
HTTP协议中关于压缩传输的规定:
第一:客户端传输到服务器请求中带有:Accept-Encoding:gzip, deflate 字段,向服务器表示,客户端支持的压缩格式(gzip或者deflate),如果不发送该消息头,服务器是不会压缩的。
第二:服务器端在收到请求之后,如果发现请求头中含有Accept-Encoding字段,并且支持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带Content-Encoding:gzip消息头,表示响应报文是根据该格式压缩过的。
第三:客户端接收到请求之后,先判断是否有Content-Encoding消息头,如果有,按该格式解压报文。否则按正常报文处理。
HTTP compression支持的压缩格式是gzip或者deflate,常用的是gzip,gzip压缩的比率往往在3到10倍,也就是本来90k大小的页面,采用压缩后实际传输的内容大小只有28至30K大小,这可以大大节省服务器的网络带宽,同时如果应用程序的响应足够快时,网站的速度瓶颈就转到了网络的传输速度上,因此内容压缩后就可以大大的提升页面的浏览速度。

gzip对webservice的意义

我们知道webservice服务器与客户端的数据传送一般也是基于http传输xml格式的文本数据。一般的数据序列化成xml格式文本后体积会变大,如果启动http压缩可以大大减少数据传送量,也就减少了网络延迟,可以改善webservice应用的总体性能。

GSoap生成的C++客户端代码是可以支持gzip压缩的,但要在代码中启用gzip压缩,需要设置编译选项。

下面是我的gsoap 客户端c++代码的cmake编译脚本。
CMakeLists.txt

#cmake file for facedbservice_stub library#author:guyadong#created:2016/08/24############################################################################cmake_minimum_required( VERSION 3.1 )# 设置变量,表示所有的源文件列表  set(SOURCE_FILES    stdsoap2.cpp    facedbserviceC.cpp    facedbserviceClient.cpp    struct_tm.cpp    nsmap.cpp                 )  add_library(facedbservice_stub ${SOURCE_FILES})# 定义GSoap是否对发送数据进行压缩的选项,默认为ONoption(WITH_GSOAP_GZIP "compress data with GZIP in gsoap " ON)if(WITH_GSOAP_GZIP)    if(ZLIB_LIBRARY_STATIC)        set (z_static ${ZLIB_LIBRARY_STATIC})        include_directories(    ${INCLUDE_ZLIB})    else()        # 使用gcc编译器自带的zlib库        set (z_static z)    endif()    # 设置gsoap编译选项,指定支持zip数据压缩    # 参见 http://www.genivia.com/doc/soapdoc2.html#tth_sEc9.11    set_target_properties(facedbservice_stub PROPERTIES COMPILE_FLAGS   "-DWITH_ZLIB -DWITH_GZIP")      # zlib 支持    target_link_libraries(facedbservice_stub ${z_static})endif(WITH_GSOAP_GZIP)if(CMAKE_SYSTEM_NAME MATCHES "Linux")    ############linux下静态链接c++库###################    set_target_properties(facedbservice_stub PROPERTIES  LINK_FLAGS "-static-libstdc++")endif()# MinGW编译时增加ws2_32支持if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX)    target_link_libraries(facedbservice_stub ws2_32)endif(WIN32 AND CMAKE_COMPILER_IS_GNUCXX)

脚本中用一个名为WITH_GSOAP_GZIP 的CMAKE选项控制是否启用gzip压缩,如果选项使用gzip压缩,则会在编译gsoap stub代码时加入WITH_ZLIBWITH_GZIP宏定义

另外请注意,启动gzip压缩,需要zlib库的支持,也请参见上面的cmake脚本。

下面是gsoap调用代码示例,在执行gsoap调用之前,使用soap_set_omode宏函数设置soap的输出模式为SOAP_IO_CHUNK| SOAP_ENC_ZLIB才真正在发送之前启用了gzip压缩。
关于gsoap 的gzip压缩的详细说明参见《gsoap手册:19.28 Zlib Compression》

const char* soap_endpoint = "http://gdface.wicp.net:15865/axis2/services/FaceDbService";// 根据SOAP版本(SOAP 1.1/SOAP 1.2)返回异常详细信息描述对象的指针SOAP_ENV__Detail* getFaultDetail(soap &soap) {    return  soap.version == 2 ? soap.fault->SOAP_ENV__Detail : soap.fault->detail;}decltype(_ns1__sdk_USCOREdetectFaceResponse::return_) detectFace(uint8_t *pImgData,size_t nSize) {    soap soap;#ifdef WITH_GSOAP_GZIP// 启用GZIP压缩 参见 http://www.genivia.com/doc/soapdoc2.html#tth_sEc19.28    soap_set_omode(&_soap,SOAP_IO_CHUNK| SOAP_ENC_ZLIB);#endif    _ns1__sdk_USCOREdetectFace param;    _ns1__sdk_USCOREdetectFaceResponse ret;    xsd__base64Binary b;    b.soap = &soap;    b.__ptr = pImgData;    b.__size = decltype(b.__size)(nSize);    param.imgData = &b;    // soap远程调用    soap_call___ns1__sdk_USCOREdetectFace(&soap, soap_endpoint, nullptr, &param, ret);    if (soap.error != SOAP_OK) {        // 错误处理代码。。。    }    return ret.return_;}

服务器端的gzip支持设置

只是gsoap客户端启用了gzip压缩还不够,还要确保webservice服务器也要支持gzip压缩,各种web服务器对gzip压缩支持的设置都不一样,可以从网上找各相关资料,以tomcat为例,参见这个文章:
《Tomcat7中开启gzip压缩功能的配置方法》,此文中还提供了测试web服务器gzip是否开启的方法。更详细的tomcat官网说明参见《The HTTP Connector:Standard Implementation》

参考资料:

《Apache启用GZIP压缩网页传输方法》
《IIS6.0开启gzip压缩》
《HTTP_compression》
《HTTP中的GZIP压缩实现》
《Web服务器处理HTTP压缩之gzip、deflate压缩》
《9.11 Library Build Flags》
《The HTTP Connector:Standard Implementation》

0 0