使用lacewing解决HTTP+XML接口问题
来源:互联网 发布:phxsql mysql 5.7 编辑:程序博客网 时间:2024/06/07 05:44
一、背景
文章背景来源于十二五课题与西屋的SystematICS综合监控的接口问题,其中History Recorder服务部署为对外数据发布的接口。History Recorder服务允许SystematICS服务对象数据和列表数据配置成存储并转发给外系统处理软件。外系统处理软件需要在History Recorder中配置,这样综合监控软件可以监视它的连接状态。可以使用文件或者配置工具配置History Recorder服务,需要配置的信息主要有:
• 表示数据要发送到的应用程序的路径;
• 所要发送给应用程序的数据;
• 所要发送给应用程序的表格。
History Recorder服务使用HTTP协议向外系统发送数据,ISCS将根据配置主动连接到外系统的web服务,首次连接后将发送全部数据,之后将发送变化数据并定期更新全部数据。外系统的web服务需至少响应前3个http消息(回应200 OK)。
发送设备状态(数据点)的格式如下:
---------------http头------------------
POST / HTTP/1.1
host:192.10.36.36:808
content-location: oil://scada.TMS/hpx_prc_do_0000
content-type: application/calendar+xml
content-length:111
---------------data区------------------
<vjournal>
<tags>bad</tags>
<dtstart>2009-02-25T10:01:19.933723Z</dtstart>
<description>1</description>
</vjournal>
---------------结束------------------
发送数据时是以XML包封装内容,基于这些情况描述,西屋的对外接口类似SOAP协议。
二、Lacewing
这篇文章主要讲述怎样把Web Server集成到你的Win32 C++应用中。使用lacewing网络库编写的C++ Web应用程序具有更快的速度和良好的伸缩性,占用系统资源极低。liblacewing 是一个跨平台的高级网络库,用于C和C++。旨在提供一组直观的Socket通讯类,侧重于稳定性和平台优化(支持IOCP, epoll 和kqueue)。
Lacewing::Webserver 作为一个功能强大的HTTP server, 主要有以下特征:
•HTTP GET/POST with automatic parameter parsing
•Non-blocking file sending
•Cookies and sessions
•Multipart file upload
•Getting/setting the last modified date, to easily implement caching
•Full HTTPS support
Lacewing源代码:http://lacewing-project.org/
三、测试环境
1、 操作系统
WINDOWS 7
2、系统
处理器:Intel(R) Core(TM) i5-2401M CPU @ 2.30GH 2.30GH
安装内存:3.00GB (2.88 GB可用)
系统类型:32位操作系统
3、工具环境
A、vc++6.0
B、VS2008
四、创建Web Server Project
下载Lacewing源代码,使用VS2008编译之后会在bin目录下产生lacewind.dll和lacewing.lib。
使用VS2008创建一个testWebServer WIN32控制台工程。同时,把lacewind.dll和lacewing.lib复制到工程文件目录下,在工程属性中配置包含lacewing.lib文件。
// testWebServer.cpp : Defines the entry point for the console application.//#include "lacewing.h"#include <assert.h>#include <string.h>#import <msxml4.dll>using namespace MSXML2;void PaserXml(BSTR bstXML){ MSXML2::IXMLDOMDocumentPtr pDoc; HRESULT hr;hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40)); if (FAILED(hr)) { printf("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!"); return ; } try { // 加载文件// pDoc->load("test.xml");pDoc->loadXML(bstXML);long lChilds, i;// 根节点MSXML2::IXMLDOMElementPtr pRootElement = pDoc->GetdocumentElement();printf("root = %s\n", (char *)pRootElement->GetnodeName());// 根节点的一级子节点MSXML2::IXMLDOMNodeListPtr pNodeList = pRootElement->GetchildNodes();lChilds = pNodeList->Getlength();char szNodeName[48], szValue[64];for (i = 0; i < lChilds; i++){MSXML2::IXMLDOMNodePtr pNode = pNodeList->Getitem(i);// 过滤注释节点if (pNode->GetnodeType() != MSXML2::NODE_COMMENT){BSTR bstrNodeName = pNode->GetnodeName();char *lpszNodeName = _com_util::ConvertBSTRToString(bstrNodeName);strncpy(szNodeName, lpszNodeName, sizeof(szNodeName));delete []lpszNodeName;BSTR bstrValue = pNode->Gettext();char *lpszValue = _com_util::ConvertBSTRToString(bstrValue);strncpy(szValue, lpszValue, sizeof(szValue));delete []lpszValue;printf("%s:%s\n", szNodeName, szValue);}}}catch (_com_error &e) {printf("Description = '%s'\n", (char*)e.Description()); if (pDoc){ pDoc.Release();} }}void onGet(Lacewing::Webserver &, Lacewing::Webserver::Request &Request){ /* The MIME type defaults to "text/html" */ Request.SetMimeType("text/html"); Request.WriteFile("post.html");}Void onPost(Lacewing::Webserver &Webserver, Lacewing::Webserver::Request &Request){// 这里szBody将显示HttpPost发送的XML格式化数据//<vjournal>// <tags>bad</tags>// <dtstart>2009-02-25T10:01:19.933723Z</dtstart>// <description>1</description>//</vjournal>char *szBody = (char *)Request.Body();BSTR bstrBody = _com_util::ConvertStringToBSTR(szBody);PaserXml(bstrBody);::SysFreeString(bstrBody);Request << "Hello SystematICS!";struct Lacewing::Webserver::Request::Header * Header = NULL; for (Header = Request.FirstHeader(); Header; Header = Header->Next()) { const char *szName = Header->Name();const char *szValue = Header->Value(); } Lacewing::Webserver::Request::Parameter *p = NULL; for (p = Request.POST(); p; p = p->Next()) {const char *szName = p->Name();const char *szValue = p->Value(); }}int main(int argc, char * argv[]){ CoInitialize(NULL); Lacewing::EventPump EventPump; Lacewing::Webserver Webserver(EventPump); Webserver.onGet(onGet); Webserver.onPost(onPost); Webserver.Host(8080); EventPump.StartEventLoop(); CoUninitialize(); return 0;}
五、创建HTTP Post Project
使用VS6创建一个testHttpPost WIN32控制台工程。
// testHttpPost.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <string>#include <iostream>#import <msxml4.dll>using namespace MSXML2;std::wstring GenerateData(){std::wstring wvarQuery;IXMLDOMDocumentPtr pDoc;IXMLDOMElementPtr xmlRoot;// 创建DOMDocument对象HRESULT hr = pDoc.CreateInstance(__uuidof(DOMDocument40));if (!SUCCEEDED(hr)){ printf("无法创建DOMDocument对象,请检查是否安装了MS XML Parser运行库!");return wvarQuery;}// 根节点的名称为vjournal// 创建元素并添加到文档中xmlRoot = pDoc->createElement("vjournal");pDoc->appendChild(xmlRoot);IXMLDOMElementPtr pNode;// 添加“tags”元素pNode = pDoc->createElement("tags");pNode->Puttext((const char *)"bad");xmlRoot->appendChild(pNode);// 添加“dtstart”元素pNode = pDoc->createElement("dtstart");pNode->Puttext((const char *)"2009-02-25T10:01:19.933723Z");xmlRoot->appendChild(pNode);// 添加“description”元素pNode = pDoc->createElement("description");pNode->Puttext((const char *)"1");xmlRoot->appendChild(pNode);// 保存到文件,如果存在就覆盖,否则不存在就建立.// pDoc->save("test.xml");wvarQuery = pDoc->Getxml(); return wvarQuery;}void PaserXml(BSTR bstXML){ IXMLDOMDocumentPtr pDoc; HRESULT hr; hr = pDoc.CreateInstance(__uuidof(DOMDocument40)); if (FAILED(hr)) { printf("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!"); return ; } // 加载文件 // pDoc->load("test.xml"); // 加载内存 pDoc->loadXML(bstXML);long lChilds, i;// 根节点IXMLDOMElementPtr pRootElement = pDoc->GetdocumentElement(); printf("root = %s\n", (char *)pRootElement->GetnodeName()); // 根节点的一级子节点 IXMLDOMNodeListPtr pNodeList = pRootElement->GetchildNodes(); lChilds = pNodeList->Getlength(); char szNodeName[48], szValue[64]; for (i = 0; i < lChilds; i++) { IXMLDOMNodePtr pNode = pNodeList->Getitem(i);// 过滤注释节点if (pNode->GetnodeType() != NODE_COMMENT){BSTR bstrNodeName = pNode->GetnodeName();char *lpszNodeName = _com_util::ConvertBSTRToString(bstrNodeName);strncpy(szNodeName, lpszNodeName, sizeof(szNodeName));delete []lpszNodeName;BSTR bstrValue = pNode->Gettext();char *lpszValue = _com_util::ConvertBSTRToString(bstrValue);strncpy(szValue, lpszValue, sizeof(szValue));delete []lpszValue;printf("%s:%s\n", szNodeName, szValue); } }}void SendData(std::wstring url){ long lState, lStatus; HRESULT hr; IXMLHTTPRequestPtr pIXMLHTTPRequest; IXMLDOMDocumentPtr pXMLDoc; try { hr = pIXMLHTTPRequest.CreateInstance(__uuidof(XMLHTTP)); SUCCEEDED(hr) ? 0 : throw hr; hr = pIXMLHTTPRequest->open("POST", url.c_str(), false); SUCCEEDED(hr) ? 0 : throw hr; // 如果要向服务器post数据,这个地方一定要设置为application/x-www-form-urlencoded pIXMLHTTPRequest->setRequestHeader("Content-Type", "application/x-www-form-urlencoded");std::wstring wvarQuery = GenerateData();_variant_t vartQueryFields(wvarQuery.c_str());PaserXml(vartQueryFields.bstrVal);hr = pIXMLHTTPRequest->send(vartQueryFields); SUCCEEDED(hr) ? 0 : throw hr; // 处理返回的xml数据,对返回的xml数据进行解析,主要是dom方法. pXMLDoc = pIXMLHTTPRequest->responseXML;// Retrieve the statepIXMLHTTPRequest->get_readyState(&lState);if (lState == 4){// The request has completed.// Get the request status.pIXMLHTTPRequest->get_status(&lStatus);if (lStatus == 200){// Get the response body if we were successful.BSTR bstrbody;pIXMLHTTPRequest->get_responseText(&bstrbody);char *lpszBody = _com_util::ConvertBSTRToString(bstrbody);// 这里将显示WebServer body区的数据“Hello SystematICS!”delete []lpszBody;} } } catch (_com_error &e) {printf("Description = '%s'\n", (char*)e.Description()); if (pIXMLHTTPRequest){pIXMLHTTPRequest.Release();} if (pXMLDoc){ pXMLDoc.Release();} }}int main(int argc, char* argv[]){CoInitialize(NULL); SendData(L"http://localhost:8080");CoUninitialize(); return 0;}
六、测试
1)、HTTP CLIENT发送:
POST / HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Host: localhost:8080
Content-Length: 113
Connection: Keep-Alive
Cache-Control: no-cache
<vjournal><tags>bad</tags><dtstart>2009-02-25T10:01:19.933723Z</dtstart><description>1</description></vjournal>
注意:文本最后是“\r\n\r\n”两个回车换行结束。
2)、HTTP SERVER接收:
POST / HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Host: localhost:8080
Content-Length: 113
Connection: Keep-Alive
Cache-Control: no-cache
<vjournal><tags>bad</tags><dtstart>2009-02-25T10:01:19.933723Z</dtstart><description>1</description></vjournal>
注意:文本最后是“\r\n\r\n”两个回车换行结束。
3)、HTTP SERVER响应: "HTTP/1.1 200 OK\r\nContent-Length:0\r\n\r\n"
即:
HTTP/1.1 200 OK
Content-Length:0
注意:文本最后是“\r\n\r\n”两个回车换行结束。长度为0表示BODY为空字符串。
完
- 使用lacewing解决HTTP+XML接口问题
- springmvc http 接口使用 img 方式解决跨域问题
- iOS解决http请求不能使用问题
- HTTP+XML方式接口数据传输
- HTTP接口发送XML短信
- http接口乱码问题
- 使用ICallBackEventHandler接口,后台使用Response.End问题的解决
- spring 使用一般接口 返回数据null 的问题 解决
- 使用dispatch_group_t 解决多个接口协调调用问题
- 解决Xcode7 使用NSURLSession发送HTTP请求时报错问题
- 使用http-proxy-middleware解决前端开发中跨域的问题
- 一次http接口调试问题
- 使用spring 的action-servlet.xml解决struts线程问题
- HTTP + XML 报文的接口开发
- 接口测试小工具(HTTP + XML)
- (封装xml)访问HTTP 接口2
- 解决log4j.xml问题http//jakarta.apache.org/log4j/ uri is not registered
- 解决 log4j.xml 问题 http//jakarta.apache.org/log4j/ uri is not registered 的方法
- 注册机使用方法
- arm-linux-ld lds脚本文件
- 红黑树(Red Black Tree)
- Exchange 2010 sp2使用脱机地址簿策略隔离用户访问!
- Sublime Text 2 使用以及破解
- 使用lacewing解决HTTP+XML接口问题
- 毛路:有些事,让别人相信就行了
- ExtJS4新发现08_改变字体大小提示
- Hadoop体系结构指南
- 快速学习html、css的经典笔记(不看后悔偶)
- CGI C编程
- 主主循环同步配置
- strtok和strtok_r的源代码分析
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图 .