Qt+QtWebApp開發筆記(一):QtWebApp介紹、下載和搭建基礎封裝http輕量級伺服器Demo
前言
Demo
下載地址
QtWebApp(HTTP Server in C++)
概述
// The main program starts the HTTP serverint main(int argc, char *argv[]){ QCoreApplication app(argc,argv); new HttpListener( new QSettings("configfile.ini", QSettings::IniFormat, &app), new MyRequestHandler(&app), &app); return app.exec();}// The request handler receives and responds HTTP requestsvoid MyRequestHandler::service(HttpRequest& request, HttpResponse& response){ // Get a request parameters QByteArray username=request.getParameter("username"); // Set a response header response.setHeader("Content-Type", "text/html; charset=UTF-8"); // Generate the HTML document response.write("<html><body>"); response.write("Hello "); response.write(username); response.write("</body></html>");}
QtWebApp下載地址
編寫Web伺服器應用程式環境
Windows
Linux
sudo apt install build-essential gdb libgl1-mesa-dev
yum groupDebian, Ubuntunstall "C Development Tools and Libraries"sudo yum install mesa-libGL-devel
sudo zypper install -t pattern devel_basis
執行下載的Demo(這裡是ubuntu環境)
如何使用QtWebApp
在自己的程式中構建
QT += networkinclude(../QtWebApp/QtWebApp/httpserver/httpserver.pri)
配置引數
[listener];host=192.168.0.100port=8080minThreads=4maxThreads=100cleanupInterval=60000readTimeout=60000maxRequestSize=16000maxMultiPartSize=10000000
OTHER_FILES += etc/webapp1.ini
#include <QCoreApplication>#include <QSettings>int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); QSettings* listenerSettings= new QSettings("/home/sfrings/programming/MyFirstWebApp/etc/webapp1.ini",QSettings::IniFormat,&app); qDebug("config file loaded"); return app.exec();}
#include <QCoreApplication>#include <QSettings>#include <QFile>#include <QDir>#include <QString>/** * Search the configuration file. * Aborts the application if not found. * @return The valid filename */QString searchConfigFile() { QString binDir=QCoreApplication::applicationDirPath(); QString appName=QCoreApplication::applicationName(); QString fileName("Demo1.ini"); QStringList searchList; searchList.append(binDir); searchList.append(binDir+"/etc"); searchList.append(binDir+"/../etc"); searchList.append(binDir+"/../"+appName+"/etc"); // for development with shadow build (Linux) searchList.append(binDir+"/../../"+appName+"/etc"); // for development with shadow build (Windows) searchList.append(QDir::rootPath()+"etc/opt"); searchList.append(QDir::rootPath()+"etc"); foreach (QString dir, searchList) { QFile file(dir+"/"+fileName); if (file.exists()) { fileName=QDir(file.fileName()).canonicalPath(); qDebug("Using config file %s",qPrintable(fileName)); return fileName; } } // not found foreach (QString dir, searchList) { qWarning("%s/%s not found",qPrintable(dir),qPrintable(fileName)); } qFatal("Cannot find config file %s",qPrintable(fileName)); return nullptr;}int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); // Load the configuration file QString configFileName=searchConfigFile(); QSettings* listenerSettings=new QSettings(configFileName, QSettings::IniFormat, &app); qDebug("config file loaded"); return app.exec();}
#include <QCoreApplication>#include <QSettings>#include <QFile>#include <QDir>#include <QString>#include "httplistener.h"#include "httprequesthandler.h"using namespace stefanfrings;int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); // Load the configuration file QString configFileName=searchConfigFile(); QSettings* listenerSettings=new QSettings(configFileName, QSettings::IniFormat, &app); listenerSettings->beginGroup("listener"); // Start the HTTP server new HttpListener(listenerSettings, new HttpRequestHandler(&app), &app); return app.exec();}
編寫自己的請求處理程式
helloworldcontroller.h:
#ifndef HELLOWORLDCONTROLLER_H#define HELLOWORLDCONTROLLER_H#include "httprequesthandler.h"using namespace stefanfrings;class HelloWorldController : public HttpRequestHandler { Q_OBJECTpublic: HelloWorldController(QObject* parent=0); void service(HttpRequest& request, HttpResponse& response);};#endif // HELLOWORLDCONTROLLER_H
helloworldcontroller.cpp:
#include "helloworldcontroller.h"HelloWorldController::HelloWorldController(QObject* parent) : HttpRequestHandler(parent) { // empty}void HelloWorldController::service(HttpRequest &request, HttpResponse &response) { response.write("Hello World",true);}
#include "helloworldcontroller.h" new HttpListener(listenerSettings,new HelloWorldController(&app),&app);
Qt的http服務Demo搭建流程(windows)
步驟一:下載QtWebApp
步驟二:新建工程testHttpDemo
步驟三:複製http
# httpserver模組,QtWebApp自帶的三方模組include ($$PWD/modules/httpserver/httpserver.pri)
步驟四:自建http管理類用模組化
步驟五:寫一個Hello world的展示訊息處理
步驟六:在http執行管理類中啟用這個監聽
步驟七:測試
步驟八:編碼一刀切處理
步驟九:打成執行包單獨執行再測試伺服器
模組化
Demo原始碼
HttpServerManager.h
#ifndef HTTPSERVERMANAGER_H#define HTTPSERVERMANAGER_H#include <QObject>#include <QMutex>#include "httplistener.h"#include "HelloWorldRequestHandler.h"class HttpServerManager : public QObject{ Q_OBJECTprivate: explicit HttpServerManager(QObject *parent = 0);public: static HttpServerManager *getInstance();public: QString getIp() const; // 伺服器監聽ip(若為空,則表示監聽所有ip quint16 getPort() const; // 伺服器監聽埠 int getMinThreads() const; // 空閒最小執行緒數 int getMaxThreads() const; // 負載最大執行緒數 int getCleanupInterval() const; // 空執行緒清空間隔(單位:毫秒) int getReadTimeout() const; // 保持連線空載超時時間(單位:毫秒) int getMaxRequestSize() const; // 最大請求數 int getMaxMultiPartSize() const; // 上載檔案最大數(單位:位元組)public: void setIp(const QString &ip); // 伺服器監聽ip(若為空,則表示監聽所有ip void setPort(const quint16 &port); // 伺服器監聽埠 void setMinThreads(int minThreads); // 空閒最小執行緒數 void setMaxThreads(int maxThreads); // 負載最大執行緒數 void setCleanupInterval(int cleanupInterval); // 空執行緒清空間隔(單位:毫秒) void setReadTimeout(int readTimeout); // 保持連線空載超時時間(單位:毫秒) void setMaxRequestSize(int value); // 最大請求數 void setMaxMultiPartSize(int value); // 上載檔案最大數(單位:位元組)public slots: void slot_start(); void slot_stop();private: static HttpServerManager *_pInstance; static QMutex _mutex;private: bool _running;private: HttpListener *_pHttpListener; // http服務監聽器 QSettings *_pSettings; // 配置檔案private: QString _ip; // 伺服器監聽ip(若為空,則表示監聽所有ip) quint16 _port; // 伺服器監聽埠 int _minThreads; // 空閒最小執行緒數 int _maxThreads; // 負載最大執行緒數 int _cleanupInterval; // 空執行緒清空間隔(單位:毫秒) int _readTimeout; // 保持連線空載超時時間(單位:毫秒) int _maxRequestSize; // 最大請求數 int _maxMultiPartSize; // 上載檔案最大數(單位:位元組)};#endif // HTTPSERVERMANAGER_H
HttpServerManager.cpp
#include "HttpServerManager.h"#include <QApplication>#include <QDebug>#include <QDateTime>//#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")HttpServerManager *HttpServerManager::_pInstance = 0;QMutex HttpServerManager::_mutex;HttpServerManager::HttpServerManager(QObject *parent) : QObject(parent), _pHttpListener(0), _pSettings(0), _running(false), _port(8088), _minThreads(2), _maxThreads(10), _cleanupInterval(60000), _readTimeout(60000), _maxRequestSize(100), _maxMultiPartSize(1024*1024*1024){}HttpServerManager *HttpServerManager::getInstance(){ if(!_pInstance) { QMutexLocker lock(&_mutex); if(!_pInstance) { _pInstance = new HttpServerManager(); } } return _pInstance;}void HttpServerManager::slot_start(){ if(_running) { LOG << "It's running!!!"; return; } _running = true; LOG << "Succeed to run"; // 啟動http的監聽 { QString httpServerPath = QString("%1/etc/httpServer.ini").arg(qApp->applicationDirPath()); if(!_pSettings) { LOG << httpServerPath << "exit:" << QFile::exists(httpServerPath); _pSettings = new QSettings(httpServerPath, QSettings::IniFormat); }#if 0 if(!_ip.isEmpty()) { _pSettings->setValue("host" , _ip); // ;在ini裡面是註釋了 } _pSettings->setValue("port" , _port); _pSettings->setValue("minThreads" , _minThreads); _pSettings->setValue("maxThreads" , _maxThreads); _pSettings->setValue("cleanupInterval" , _cleanupInterval); _pSettings->setValue("readTimeout" , _readTimeout); _pSettings->setValue("maxRequestSize" , _maxRequestSize); _pSettings->setValue("maxMultiPartSize", _maxMultiPartSize);#endif _pHttpListener = new HttpListener(_pSettings, new HelloWorldRequestHandler); }}void HttpServerManager::slot_stop(){ if(!_running) { LOG <<"It's not running!!!"; return; } _running = false; LOG << "Succeed to stop";}int HttpServerManager::getMaxMultiPartSize() const{ return _maxMultiPartSize;}void HttpServerManager::setMaxMultiPartSize(int value){ _maxMultiPartSize = value;}int HttpServerManager::getMaxRequestSize() const{ return _maxRequestSize;}void HttpServerManager::setMaxRequestSize(int value){ _maxRequestSize = value;}int HttpServerManager::getReadTimeout() const{ return _readTimeout;}void HttpServerManager::setReadTimeout(int readTimeout){ _readTimeout = readTimeout;}int HttpServerManager::getCleanupInterval() const{ return _cleanupInterval;}void HttpServerManager::setCleanupInterval(int cleanupInterval){ _cleanupInterval = cleanupInterval;}int HttpServerManager::getMaxThreads() const{ return _maxThreads;}void HttpServerManager::setMaxThreads(int maxThreads){ _maxThreads = maxThreads;}int HttpServerManager::getMinThreads() const{ return _minThreads;}void HttpServerManager::setMinThreads(int minThreads){ _minThreads = minThreads;}quint16 HttpServerManager::getPort() const{ return _port;}void HttpServerManager::setPort(const quint16 &port){ _port = port;}QString HttpServerManager::getIp() const{ return _ip;}void HttpServerManager::setIp(const QString &ip){ _ip = ip;}
HelloWorldRequestHandler.h
#ifndef HELLOWORLDREQUESTHANDLER_H#define HELLOWORLDREQUESTHANDLER_H#include "httprequesthandler.h"using namespace stefanfrings;class HelloWorldRequestHandler : public HttpRequestHandler{public: HelloWorldRequestHandler(QObject *parent = 0);public: void service(HttpRequest& request, HttpResponse& response);private: QTextCodec *_pTextCodec;};#endif // HELLOWORLDREQUESTHANDLER_H
HelloWorldRequestHandler.cpp
#include "HelloWorldRequestHandler.h"#include <QTextCodec>#include <QDebug>#include <QDateTime>//#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")using namespace stefanfrings;HelloWorldRequestHandler::HelloWorldRequestHandler(QObject *parent) : HttpRequestHandler(parent){ // 返回文字(我們需要在瀏覽器上看,所以將Qt內部編碼都轉成GBK輸出即可,不管他本身是哪個編碼) // WINDOWS: GBK GB2312 // LINUX : urf-8// _pTextCodec = QTextCodec::codecForName("utf-8"); _pTextCodec = QTextCodec::codecForName("GBK");}void HelloWorldRequestHandler::service(HttpRequest &request, HttpResponse &response){ LOG; // 返回hello world QString str = "Hello, world!!!"; str += "你好, 長沙紅胖子 QQ:21497936 // 返回文字(我們需要在瀏覽器上看,所以將Qt內部編碼都轉成GBK輸出即可,不管他本身是哪個編碼) QByteArray byteArray = _pTextCodec->fromUnicode(str); response.write(byteArray);}
入坑
入坑一:監聽配置程式碼動態寫入失敗
問題
原因
解決
入坑二:127.0.0.1無法進入
問題
原因
解決
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010283/viewspace-2952308/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Qt+QtWebApp開發筆記(二):http伺服器日誌系統介紹、新增日誌系統至Demo測試QTWebAPP筆記HTTP伺服器
- Qt+ECharts開發筆記(一):ECharts介紹、下載和Qt呼叫ECharts基礎柱狀圖DemoQTEcharts筆記
- Qt+ECharts開發筆記(三):ECharts的柱狀圖介紹、基礎使用和Qt封裝DemoQTEcharts筆記封裝
- Qwt開發筆記(一):Qwt簡介、下載以及基礎demo工程模板筆記
- Qt+ECharts開發筆記(五):ECharts的動態排序柱狀圖介紹、基礎使用和Qt封裝DemoQTEcharts筆記排序封裝
- 超輕量級MP4封裝方法介紹封裝
- 一個輕量級WebFramework開發框架介紹WebFramework框架
- Qt+ECharts開發筆記(四):ECharts的餅圖介紹、基礎使用和Qt封裝百分比圖DemoQTEcharts筆記封裝
- libmatio開發筆記(一):matlab檔案操作libmatio庫介紹,編譯和基礎DemoIBM筆記Matlab編譯
- openresty前端開發輕量級MVC框架封裝一(控制器篇)REST前端MVC框架封裝
- Qwt開發筆記(二):Qwt基礎框架介紹、折線圖介紹、折線圖Demo以及程式碼詳解筆記框架
- Qt+OpenCascade開發筆記(二):windows開發環境搭建(二):Qt引入occ庫,搭建基礎工程模板Demo和釋出DemoQT筆記Windows開發環境
- 開源輕量級辦公系統Sandbox介紹以及配套開發文件連載
- 國產輕量級BI平臺CBoard的安裝和初步使用介紹
- 地圖開發筆記(一):百度地圖介紹、使用和Qt內嵌地圖Demo地圖筆記QT
- spa-to-http:輕量級零配置SPA HTTP 伺服器HTTP伺服器
- Gif開發筆記(一):gif介紹、編譯和工程模板筆記編譯
- Linux驅動開發筆記(四):裝置驅動介紹、熟悉雜項裝置驅動和ubuntu開發雜項裝置DemoLinux筆記Ubuntu
- Solon & Solon Cloud 1.5.62 釋出,輕量級 Java 基礎開發框架CloudJava框架
- 輕量級 Java 基礎開發框架,Solon & Solon Cloud 1.5.48 釋出Java框架Cloud
- 輕量級 Java 基礎開發框架,Solon & Solon Cloud 1.5.40 釋出Java框架Cloud
- 搭建基於springboot輕量級讀寫分離開發框架Spring Boot框架
- Kinect開發學習筆記之(一)Kinect介紹和應用筆記
- 【筆記】Python基礎(二)運算子介紹筆記Python
- 開發環境搭建之一,Clion的下載和安裝開發環境
- 前端基礎之HTTP協議介紹前端HTTP協議
- Angular6筆記之封裝httpAngular筆記封裝HTTP
- 【Java面試】為什麼引入偏向鎖、輕量級鎖,介紹下升級流程Java面試
- 公司官網建站筆記(三):騰訊雲伺服器CentOS8.2安裝介面環境,搭建輕量級Qt伺服器筆記伺服器CentOSQT
- Qt+騰訊IM開發筆記(一):騰訊IM介紹、使用和Qt整合騰訊IM-SDK的工程模板DemoQT筆記
- HTTP2基礎教程-讀書筆記(一)發展史和誕生背景HTTP筆記
- 24. 企業級開發基礎5:物件導向特徵(封裝)物件特徵封裝
- 介紹一款輕量級js控制元件:easy.jsJS控制元件
- vue 基礎入門筆記 14:發表評論 demoVue筆記
- 基於gogs和drone的一個輕量級的開發部署自動化流程Go
- 《Python web開發》筆記 一:網頁開發基礎PythonWeb筆記網頁
- 輕量級CI/CD釋出部署環境搭建及使用_01_基本介紹
- hibernate《輕量級框架應用與開發--S2SH》筆記框架筆記