基于MS SoapClient的数据压缩方法
Ms soap应用大大简化了客户端与服务器数据库的交互过程,自动实现了于webservice的交互过程 ,减短了我们的开发时间,同时其灵活性也相当强。但是其通过http传输的数据不支持自动压缩,同时其相关的教程和可查询的资料是少之又少,查遍MSND以及google搜索也很难找到所需的资料,可以说是这个产品中的一大败笔。众所周知,soap基于xml实现了数据标识以及灵活的扩展,同时由此而产生了大量重复的标识符,压缩比相当高,对于有众多不同网络环境用户的系统而言,client和service之间进行大量数据传输的时候,由此而产生的数据膨胀是致命的,我们迫切需要对数据进行压缩。
通过搜索引擎我们可以查到一些相关的文章,大都提及到了xml序列化以及反序列化,但是缺少详细的实施步骤。下面笔者以自身切实环境讲述一下详细实施过程:
笔者的客户端环境是vc.net,服务器端apache已经配置了支持gzip压缩的组件,通过抓包分析发现,SoapClient发出的http请求中没有声明可接受gzip压缩数据,服务器发回的应答数据自然也就不会进行gzip压缩,于是笔者在请求头中加入Accept-Encoding: gzip, deflate\r\n,然后抓包分析,服务器返回的应答的确经过了压缩,但是WinINet不会自动自持gzip解压,这个工作在Windows Server“Longhorn”与 Windows Vista之前的window版本中必须由开发者来完成,对于SoapClient,我们只需要扩展一下ReadStreamOnInet的Read方法,加入具体的解压缩代码,把解压后的数据返回给调用者就OK了。
这是具体实施过程吗?呵呵,当然不是,以上只是笔者提纲挈领的表述一下主体过程。客户端具体实施过程可以分为三步:
一、修改CSoapWininetClient的SendRequest方法,在发送请求前加入
HttpAddRequestHeaders(m_hRequest, CString("Accept-Encoding: gzip, deflate\r\n"), -1, HTTP_ADDREQ_FLAG_ADD);同时修改请求头中声明的可接受类型,我是修改为:
static LPCTSTR s_szAcceptTypes[] = { _T("text/xml"), _T("text/html"), _T("*/*"), NULL };当然如果你的soapclient使用的是CsoapSocketClient,则修改CsoapSocketClient的SendRequest方法。
二、修改CReadStreamOnInet的Read方法,把解压后的数据返回给调用者。
HRESULT CGzipReadStreamOnInet::Read(void *pDest, ULONG dwMaxLen, ULONG *pdwRead)
{
BOOL bRet = TRUE;
while (bRet && (NULL != m_tmpFile))
{
bRet = InternetReadFile(m_nhFile, pDest, dwMaxLen, pdwRead);
if (*pdwRead > 0)
{
m_tmpFile->Write(pDest, *pdwRead);
}
else
{
m_tmpFile->Close();
delete m_tmpFile;
m_tmpFile = NULL;
break;
}
}
*pdwRead = 0;
if (NULL == m_gzFile)
{
m_gzFile = gzopen(CT2A(m_tmpFileName), "rb");
}
if (NULL == m_gzFile)
return E_FAIL;
int nRead = gzread(m_gzFile, pDest, dwMaxLen);
if (-1 == nRead)
return E_FAIL;
*pdwRead = nRead;
return S_OK;
}
三、修改SoapClient中的成员变量m_readStream类型为CGzipReadStreamOnInet:
class CGzipSoapClient
{
private:
CUrl m_url;
CWriteStreamOnCString m_writeStream;
CGzipReadStreamOnInet m_readStream;
CString m_strProxy;
DWORD m_dwTimeout;
CFixedStringT<CString, ATL_URL_MAX_URL_LENGTH+1> m_strUrl;
SOAPCLIENT_ERROR m_errorState;
然后编译,运行,OK。
以上是客户端的实施过程,对于服务端,如果你使用的是apache,请参阅http://www.code365.com/tech/0/80/Article/7177.Asp,可以得到具体配置信息。如果你使用的是IIS,可以从http://www.wwwcoder.com/main/parentid/170/site/3669/68/default.aspx得到相关信息,但是笔者没有具体实施验证。
页:
[1]