当前位置: 首页 > wzjs >正文

西安市沣东新城建设局网站网站推广公司

西安市沣东新城建设局网站,网站推广公司,古典网站建设,一个网站怎么留住用户1、下载http模块 上网查询发现在C中,建立HTTP服务器几乎都是用的是http-parser,然后我也准备直接使用,但是如果要在Qt中使用,这还需要自己再次封装一遍,于是乎我找到了这个示例,非常好用: leg…

1、下载http模块

上网查询发现在C++中,建立HTTP服务器几乎都是用的是http-parser,然后我也准备直接使用,但是如果要在Qt中使用,这还需要自己再次封装一遍,于是乎我找到了这个示例,非常好用:

legahero/HttpJsonServer: 用QT实现HTTP JSON服务器( http json server by QT)https://github.com/legahero/HttpJsonServer

 打开这个项目目录,需要知道的有主窗口的源文件,以及config目录、httpbase目录,分析项目结构后不难发现,config是数据库配置文件所在的目录(你如果不需要,则完全可以不用管),httpbase是封装好了的http和数据库各种类的目录,详细的下面慢慢介绍。

2、引用http模块

首先第一步是引用,上面地址的项目示例下载完成后,直接将httpbase目录copy到我们的项目目录中,然后像示例一样,在.pro文件中引用:

不要忘了加上Qt的网络模块(network)和数据库(sql)模块,如果你觉得每次建立项目都需要加上这么一堆,很麻烦,那就在httpbase目录中建立一个.pri文件,然后引用.pri文件就可以,例如:

#.pri文件内容
QT       += network sqlSOURCES += httpbase/qhttprequest.cpp \httpbase/qhttpresponse.cpp \httpbase/qhttpserver.cpp \httpbase/http_parser.c \httpbase/threadhandle.cpp \httpbase/qasyntcpserver.cpp \httpbase/qasynhttpsocket.cpp \httpbase/staticfilecontroller.cpp \httpbase/httphandler.cpp \httpbase/qasyntcpsocket.cpp \httpbase/qconnectpool.cpp \httpbase/qmultidbmanager.cppHEADERS  += httpbase/http_parser.h \httpbase/qhttprequest.h \httpbase/qhttpresponse.h \httpbase/threadhandle.h \httpbase/qasyntcpserver.h \httpbase/qasynhttpsocket.h \httpbase/qhttpserver.h \httpbase/staticfilecontroller.h \httpbase/httphandler.h \httpbase/qasyntcpsocket.h \httpbase/qhttpserverfwd.h \httpbase/qconnectpool.h \httpbase/qmultidbmanager.h#.pri文件在.pro文件中引用
include(httpbase/httpbase.pri)

3、使用http模块

首先看主窗口的源文件,就可以看到初始化http直接使用QHttpServer类就行了,不需要过多的动作,然后就找http的业务处理在哪里,在QHttpServer类中我们看定义的各种函数,一下就可以看到有个槽函数叫handleRequest,一看就知道是处理业务的函数,然后我们去看看示例中的业务处理代码如下,逐字逐句分析,这里使用注释讲解:

//处理新的http 请求,这里处理业务
void QHttpServer::handleRequest(QHttpRequest *req, QHttpResponse *resp)
{qDebug() << "QHttpServer:handleRequest,ThreadId:"<<QThread::currentThreadId()  ;qDebug() <<"path:"<< req->path()<<"body:"<<req->body();//打印请求路径和消息内容qDebug() <<"headers:"<< req->headers();//打印请求头,是hash表类型的数据if(req->path().indexOf('.')>=0)//如果请求的是根目录中的文件,则使用文件转发模块{QString configFileName=searchConfigFile();// Configure static file controllerQSettings* fileSettings=new QSettings(configFileName,QSettings::IniFormat);fileSettings->beginGroup("docroot");StaticFileController* staticFileController=new StaticFileController(fileSettings);//StaticFileController staticFileController(fileSettings);staticFileController->Handler(*req, *resp);return ;}QJsonDocument doc=QJsonDocument::fromBinaryData(req->body());//这里接收到的数据是二进制形式的数据,所以使用fromBinaryData函数,如果是utf8格式使用fromJsonQJsonObject recv_obj=doc.object();//这是接收到的json对象QConnectPool* dbpool=QMultiDbManager::getDb("sql2014");//获取sql2014数据库句柄if(dbpool!=NULL){QSqlDatabase db=dbpool->openSession();QSqlQuery query(db);query.exec("SELECT top 1 * FROM tLogin ");//查询用户列表QJsonObject resp_obj; //返回json对象while (query.next()) {//将用户数据打包进返回json数据中resp_obj.insert("LoginName",query.value("LoginName").toString());resp_obj.insert("Pwd", query.value("LoginName").toString());}dbpool->closeSession(db);//关闭数据库QByteArray data = QJsonDocument(resp_obj).toJson(QJsonDocument::Compact);resp->setHeader("Content-Type", "text/html");//设置请求头,返回数据类型resp->setHeader("Content-Length", QString::number(data.length()));//返回消息内容大小resp->writeHead(200);//写入请求头,并带有返回码200表示请求成功resp->end(data);//写入完毕,顺便带入最后的消息。可以去定义处看,一般写入使用函数write}else{qDebug() <<"get  QMultiDbManager::getDb fail";//resp->setHeader("Content-Type", "text/html");resp->writeHead(403);//这里数据库打开失败了,返回403}resp->flush();//开始回收资源req->deleteLater();resp->deleteLater();qDebug() <<"handleRequest end";}

上述就是大概的使用流程了,关于请求业务类型的区分,查看QHttpRequest类的定义可以看到枚举类型HttpMethod,就可以知道有哪些业务请求类型了,然后两个函数获取当前请求的类型method()和methodString()。

4、使用过程中会遇到的问题

(1)消息主体为空

打印req->body()没有消息,看程序输出日志readall有,说明解析后的消息内容没有添加到QHttpRequest类中,在哪里断层了,跟踪解析逻辑后来到QAsynHttpSocket类,这里是进行消息各个值赋值的地方,分析各个私有变量后发现当前临时的消息主体QByteArray m_currentBody,然后查看QHttpRequest中实例化了QAsynHttpSocket类同样是私有成员,所以为了直接能够在业务处理中打印m_currentBody,所以定义两个公有的函数:

//QAsynHttpSocket类中,这个直接复制在头文件的公有定义中const QByteArray &getCurTempbody() const{return m_currentBody;}//QHttpRequest类中
QByteArray QHttpRequest::getCurTempbody()
{if(m_connection == nullptr){return "";}return m_connection->getCurTempbody();
}

然后调试打印,发现m_currentBody就是最新的那个消息内容,准确无误了,再次分析QAsynHttpSocket类,发现函数doMessageComplete()的功能就是构建QHttpRequest类,并传递出去,那我们就在这里添加消息主体内容,问题解决:

Q_EMIT request->data(theConnection->m_currentBody);//分析后发现该信号就是添加内容的,我们直接将当前临时的消息发送过去就行了Q_EMIT theConnection->newRequest(request, response);//这是发送构建完成的信号,在这里之前添加内容

(2)请求文件资源一直失败

测试访问文件资源一直失败,打印发现一直提示termiteHttpServer.ini文件未找到,这个时候也可以看到根目录为“./etc”,那我们就直接在这里创建termiteHttpServer.ini文件,因为跟踪查看,发现其实什么内容都不用添加,再访问仍旧失败,业务处理函数中,直接看staticFileController->Handler(*req, *resp);一句,这里转发文件,分析函数Handler后可以知道这里缺少请求头,消息内容的长度以及应答状态码,我们找到下面的第一行代码,然后将后续两行直接添加即可:

response.setHeader("Cache-Control","max-age=" + QByteArray::number(maxAge/1000));
response.setHeader("Content-Length", QString::number(file.size()));//文件大小
response.writeHead(200);//状态码

http://www.dtcms.com/wzjs/312186.html

相关文章:

  • asp.net开发微网站开发建站公司最新报价
  • 公司网站重新建站通知淄博网站优化
  • 沙朗镇做网站公司sem是什么意思职业
  • 怎么做外围网站代理申请域名
  • 南阳网站排名公司口碑营销策划方案
  • 做影视网站 片源从哪里来如何做市场调研和分析
  • 域名备案名称江门搜狗网站推广优化
  • 银川做网站的有哪些东莞疫情最新消息通知
  • vps搭建网站网站搜索系统
  • 做网站会有侵权网站制作公司排行榜
  • 正保建设工程网站线上推广的公司
  • 建立网站怎么做关键字app推广刷量
  • 韩城网站建设韩城网站推广优化防控措施
  • wordpress加入aiaso优化
  • 安徽盛绿建设网站体验营销是什么
  • 青白江建设网站产品推广活动策划方案
  • 做网站用什么软件ps字体湖北网站seo策划
  • 包小盒设计网站短视频推广平台有哪些
  • 英山做网站多少钱开封网络推广公司
  • 做网站纸张大小百度互联网营销顾问
  • 搜索引擎和门户网站的区别手机百度2020最新版
  • 河南省建设银行网站年报合肥优化推广公司
  • 做游乐设施模型的网站深圳网站优化公司
  • 台州模板网建站世界杯积分榜排名
  • 做阿里巴巴网站多少钱seo优化网络推广
  • 公司网站怎么做海淀网站建设公司
  • 贵阳网站推广如何在微信上做广告
  • wordpress memcached redux郑州seo优化顾问阿亮
  • 做旅游网站的写手免费建站网站大全
  • 东莞市网站建设公司榆林seo