Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo |
您所在的位置:网站首页 › qt怎么编译运行代码 › Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo |
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… Qt开发专栏:三方库开发技术上一篇:没有了 下一篇:《Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试》 前言在arm上做了Qt的应用程序,为了在局域网实现web页的访问方式来配置arm上Qt的程序,局域网轻量级http服务器是很好的实现方式之一,有机会做国产麒麟上Qt的http服务器,正好接触到了QtWebApp可以实现。 本篇实战解说QtWebApp的轻量级Demo。 本篇篇幅较长,为了保持基础的完整性将必要的东西都放在本篇。 Demo 链接:https://pan.baidu.com/s/1tSFWCTsbPY5c1rWo2Mxz_Q?pwd=1234 QtWebApp(HTTP Server in C++) 概述QtWepApp是一个C++中的HTTP服务器库,其灵感来自Java Servlet。适用于Linux、Windows、Mac OS和Qt Framework支持的许多其他操作系统。 QtWebApp包含以下组件: HTTP(S)1.0和1.1服务器模板引擎缓冲记录器 这些组件可以相互独立地使用。一个非常小的用法示例: // The main program starts the HTTP server int 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 requests void 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(""); response.write("Hello "); response.write(username); response.write(""); }大约2MB的小内存需求使web服务器有资格用于嵌入式系统(PS:非常符合后续arm产品定位)。对于更大的网络服务来说,它也足够强大。 记录器通过将调试消息保留在内存中直到出现错误来提高磁盘空间和性能。只要一切正常,就不会编写调试消息。 对记录器配置的更改将自动变为活动状态,而无需重新启动程序。 该库使用Qt 4.7至6.x版本运行。如果是Qt 6,则需要安装Qt5Compat库。它包含对许多8位字符编码的支持,Qt6默认情况下不再支持这些编码。可以在LGPL许可证的条件下使用该软件。 作者项目的起源 多年前,一位经验丰富的Java开发人员坚持认为Java是互联网语言,因为在其他编程语言中进行互联网通信要复杂得多。这不正确,但拒绝相信。所以开始挑战。 任务:与Qt4相比,仅使用Java 6运行时库对具有一些基本功能的HTTP服务器进行编程。 两个项目都很相似,实现了任务。同时,Qt/C++程序比Java版本小得多,也快得多。 几年后,用这个原型制作了一个库,并将其用于一些私人项目。大学鼓励发布代码。从那以后,再也不用这个项目了,但还是进行了一些改进,让人们感到高兴。 有趣的是,Qt制造商多年来一直在开发标准HTTP服务器,但到2022年,它仍然不包括在Qt库中。这也许可以解释为什么很多人使用的库。 QtWebApp下载地址官方:http://www.stefanfrings.de/qtwebapp/QtWebApp.zip 链接:https://pan.baidu.com/s/1v9DTrajX8Mv-xnhScDhN8g?pwd=1234 编写Web服务器应用程序环境使用Qt和QtWebApp在C++中开发HTTP Web服务器应用程序。必须已经了解C++和HTML的基本知识。 Windows安装好Qt,下载QtWebApp源码; Linux安装好Qt,下载QtWebApp源码,然后对应不同linux安装一些软件如下: Debian, Ubuntu sudo apt install build-essential gdb libgl1-mesa-dev Fedora, RedHat, CentOS sudo yum groupDebian, Ubuntunstall "C Development Tools and Libraries" sudo yum install mesa-libGL-devel openSUSE sudo zypper install -t pattern devel_basis 运行下载的Demo(这里是ubuntu环境) 为的编程项目创建一个目录,然后在那里下载并提取QtWebApp ZIP文件。启动QT Creator IDE并打开项目文件Demo1/Demo1.pro。这将打开“配置项目”对话框: 只需点击突出显示的“配置项目”按钮即可。然后点击左边框中的绿色“Run”按钮,构建并运行演示程序。当的计算机正忙时,可以通过单击底部边框中的相关按钮来观看“编译输出”窗格。如果一切正常,将打开一个黑色控制台窗口,告诉演示应用程序正在使用哪个配置文件: 打开URL http://localhost:8080在web浏览器中检查演示web服务器是否正常工作: 如果曾经使用Java Servlet API开发过web服务器应用程序,会感觉像在家一样。的库提供了几乎相同的功能。将向展示如何使用QtWebApp编写一个最小的web服务器应用程序。 在自己的程序中构建 提取编程文件夹中的QtWebApp.zip文件,并创建一个名为“MyFirstWebApp”的新Qt控制台项目(如果尚未完成)。然后,应该拥有与相同的文件夹结构: 将以下行添加到MyFirstWebApp项目的项目文件中: QT += network include(../QtWebApp/QtWebApp/httpserver/httpserver.pri) 第一行激活Qt的网络模块,第二行包括QtWebApp的HTTP服务器模块的源代码。因此,当编译程序时,HTTP服务器将成为可执行文件的一部分。 下一步是创建配置文件MyFirstWebApp/etc/webapp1.ini。需要使用操作系统的文件管理器来执行此操作,因为Qt Creator无法创建新文件夹。文件内容为: [listener] ;host=192.168.0.100 port=8080 minThreads=4 maxThreads=100 cleanupInterval=60000 readTimeout=60000 maxRequestSize=16000 maxMultiPartSize=10000000主机和端口参数指定web服务器侦听的IP地址和端口。如果注释掉主机(如上所述),则服务器将侦听所有网络接口。公共web服务器使用端口80,而内部web服务器通常在端口8080上侦听。可以使用任何喜欢的自由端口。 Unix用户应该记住,1024以下的端口号是为“root”用户保留的。Windows用户可能需要配置Windows防火墙以允许从其他计算机进行访问。 QtWebApp可以同时处理多个HTTP请求,因此它是多线程的。由于启动一个新线程需要花费大量时间,QtWebApp会将线程重新用于后续的HTTP请求。 maxThreads值指定并发工作线程的最大数量。在进入生产环境之前,应该使用负载生成器工具来了解服务器在不耗尽内存或变得迟缓的情况下可以处理多少负载。 minThreads空闲时并发工作线程的最小数量。web服务器总是以一个空线程池开始。线程是在HTTP请求传入时按需创建的。空闲线程由计时器缓慢关闭。每个cleanupInterval(以毫秒为单位),服务器都会关闭一个空闲线程,但是minThreads的数量总是保持运行。使用给定的值,的服务器最多可以处理100个并发HTTP连接。它保持4个空闲的工作线程运行,以确保良好的响应时间。 readTimeout设置通过打开大量连接而不使用这些连接来保护服务器免受简单的拒绝服务攻击的超时时间。空闲连接在该毫秒数之后关闭。在正常情况下,网络浏览器负责关闭连接。 maxRequestSize保护服务器不受非常大的HTTP请求造成的内存过载的影响。此值适用于常规请求。 maxMultiPartSize值适用于web浏览器将文件上载到服务器时发生的多部件请求。如果想接收10兆字节的文件,由于HTTP协议开销,必须将此值设置得稍大一些。 上传的文件存储在临时文件中。临时文件夹的位置由操作系统定义。 继续创建的第一个web应用程序。要使此配置文件在Qt Creator中可见,请在项目文件中添加一行: OTHER_FILES += etc/webapp1.ini现在添加一些代码来加载该文件: #include #include 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(); }但更喜欢在几个文件夹中自动搜索配置文件,这样就可以在IDE内外运行应用程序,而无需更改路径: #include #include #include #include #include /** * 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(); }过程searchConfigFile()在多个文件夹中搜索文件。 方法**QDir::canonicalPath()将相对路径名转换为绝对形式,这在下面的调试消息中看起来更好。 如果找不到该文件,则应用程序会输出一条带有qFatal()**的错误消息,这也会中止程序。 一旦加载了配置文件,就可以创建一个HTTP侦听器对象,它是web服务器的核心: #include #include #include #include #include #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(); } 方法**QSettings::beginGroup()**从配置文件中选择组“[listener]”。稍后将添加更多组。 HttpRequestHandler接收所有传入的HTTP请求,并生成响应。默认情况下,请求处理程序只返回一个错误页面。 在堆上用“new”创建HttpListener是很重要的,否则它将在程序启动后立即终止。 运行程序并打开URLhttp://localhost:8080在web浏览器中。将在控制台窗口中收到错误页面“501未实现”和调试消息。 因此,对于生产,应该更喜欢发布版本。 编写自己的请求处理程序 为了输出“Hello World”消息,必须编写自己的请求处理程序。用鼠标右键单击src文件夹,选择“添加新…”,然后选择“C++类”。 可选参数“true”表示这是当前HTTP请求的最后一次write()调用。 main.cpp中的两个更改: #include "helloworldcontroller.h" new HttpListener(listenerSettings,new HelloWorldController(&app),&app); 运行程序并打开URLhttp://localhost:8080在网络浏览器中。 因为http很多时候是放在一个Qt界面里面,所以搭建的是QWidget工程模板,非控制台,有需要自行切换下。 步骤一:下载QtWebApp略; 步骤二:新建工程testHttpDemo 将QtWebApp中的httpserver,符合模块化设计准则,如下图: 添加模块进入工程: httpserver模块,QtWebApp自带的三方模块 # httpserver模块,QtWebApp自带的三方模块 include ($$PWD/modules/httpserver/httpserver.pri) 第三方的模块。 步骤四:自建http管理类用模块化 再建立一个http管理类来处理,如下: 再建立基本配置: 至此,基础模块搭建好,下面需要开始写http的消息处理过程。 步骤五:写一个Hello world的展示消息处理 继承HttpRequestHandler消息处理类,开始新建一个类: 引入头文件,命名空间,做一些基础处理: 然后要实现service服务接口: 如下图: 测试127.0.0.1移植连接补上,查看 “入坑二”。 然后测试打开成功: 这里有个字符编码的问题也要同时解决一下,一般来说都是utf-8,所以要字符编码修改一下。 步骤八:编码一刀切处理 我们忽略系统编码,统一进行utf-8进行转换,避免因为系统问题而去单独处理这个问题: 然后测试网页: 除了日志,没发现三方模块中有是否监听成功的反馈,所以日志就显得很重要,日志在下一篇再融于进来 至此,一个基础子线程模块化的http服务的qt界面应用Demo就完成了。 模块化 配置文件绑定了显性ip。 解决 去掉配置文件显性ip地址: 再尝试: 上一篇:没有了 下一篇:《Qt+QtWebApp开发笔记(二):http服务器日志系统介绍、添加日志系统至Demo测试》 若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |