HTTP GETリクエストを受信して処理し、応答を送信する小さなHTTPサーバーアプリケーションを記述したいと思います。アプリケーションの履歴のため、これにはQtを使用したいと思いますが、他に(より一般的な)方向があります。サーバーに要求を送信し、 QNetworkAccessManager を使用して応答を受信します。必要なのは、リクエストが入ったときに、このリクエストのURLなどを選択できるオブジェクトを生成するソケットのようなものです。これにより、適切な応答を送信できます。
Qtフレームワークでは、私はただ盲目なのか、それともこのようなものはないのですか?もしそうなら、あなたは代替案を推奨できますか?
私はこれを見つけました https://github.com/vinipsmaker/tufao 、それは遅い答えです...それが役立つかどうかわかりません。
QtWebApp は、GETおよびPOSTメソッド、Cookie、セッション、およびファイルのアップロードをサポートするHTTPサーバーです。このライブラリの使用は、Javaサーブレット。
プロジェクトのウェブサイトはドイツ語ですが、ダウンロード可能なファイルはすべて、ドキュメントを含めてすべて英語です。
QHttpEngine の最初のバージョンをリリースしました。これは、あなたが説明したギャップを埋めることを目的としています。プロジェクトの目標は、Qtと統合するHTTPサーバーを提供する非常にシンプルなクラスのセットを提供することです。
たとえば、アプリケーションのリソースから静的ファイルを提供するために必要なことは、次のとおりです。
QFilesystemHandler handler(":/www");
QHttpServer server(&handler);
server.listen(QHostAddress::LocalHost, 8000);
QObject
から派生したクラスを作成して、そのスロットをHTTP APIのエンドポイントとして公開することもできます。例えば:
class ApiHandler : public QObjectHandler
{
Q_OBJECT
private slots:
QVariantMap doSomething(const QVariantMap ¶ms) {
// do something with the parameters and return a response
}
};
ユーザーは、JSONとしてエンコードされたパラメーターを使用してPOST /doSomething
へのリクエストを送信し、スロットが生成する応答を受信できます。
ライブラリ全体が完全に文書化されており、かなり網羅的なテストスイートが付属しています。クロスプラットフォームであり、Linux、Windows、Mac OS Xで正式にテストおよびサポートされています。QHttpEngineを使用する少なくとも1つの主要なオープンソースアプリケーション NitroShare があります。
これは非常に単純なHTTP Webサーバーで、Webブラウザーで接続が確立されてから1秒ごとに秒数を更新します。また、Webブラウザから送信されたデータを画面に表示します。プログラムはポート8080を使用するように設定されています(例:127.0.0.1:8080)
#-------------- Project file webServer3.pro -------
QT += core
QT += network
QT -= gui
TARGET = webServer3
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += \
myhttpserver.h
/*------------------header file myhttpserver.h --------------*/
#ifndef MYHTTPSERVER
#define MYHTTPSERVER
#include <QCoreApplication>
#include <QNetworkInterface>
#include <iostream>
#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QDebug>
class myHTTPserver : public QObject
{
Q_OBJECT
public:
explicit myHTTPserver(QObject *parent = 0);
~myHTTPserver();
QTcpSocket *socket ;
public slots:
void myConnection();
private:
qint64 bytesAvailable() const;
QTcpServer *server;
signals:
};
/*------------------------main.cpp -------------------------*/
#include "myhttpserver.h"
using namespace std;
void delayms( int millisecondsToWait );
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myHTTPserver server;
return a.exec();
}
myHTTPserver::myHTTPserver(QObject *parent) : QObject(parent)
{
server = new QTcpServer(this);
// waiting for the web brower to make contact,this will emit signal
connect(server, SIGNAL(newConnection()),this, SLOT(myConnection()));
if(!server->listen(QHostAddress::Any,8080))cout<< "\nWeb server could not start";
else cout<<"\nWeb server is waiting for a connection on port 8080";
}
void myHTTPserver::myConnection()
{
static qint16 count; //count number to be displayed on web browser
socket = server->nextPendingConnection();
while(!(socket->waitForReadyRead(100))); //waiting for data to be read from web browser
char webBrowerRXData[1000];
int sv=socket->read(webBrowerRXData,1000);
cout<<"\nreading web browser data=\n";
for(int i=0;i<sv;i++)cout<<webBrowerRXData[i];
cout<<"\n";
socket->write("HTTP/1.1 200 OK\r\n"); // \r needs to be before \n
socket->write("Content-Type: text/html\r\n");
socket->write("Connection: close\r\n");
socket->write("Refresh: 1\r\n\r\n"); //refreshes web browser every second. Require two \r\n.
socket->write("<!DOCTYPE html>\r\n");
socket->write("<html><body>Number of seconds since connected.. ");
QByteArray str;
str.setNum(count++); //convert int to string
socket->write(str);
socket->write(" </body>\n</html>\n");
socket->flush();
connect(socket, SIGNAL(disconnected()),socket, SLOT(deleteLater()));
socket->disconnectFromHost();
}
myHTTPserver::~myHTTPserver()
{
socket->close();
}
QttpServer = Qt + libuv + REST = APIサーバー
多数の同時接続 、リクエスト、およびwhat-have-youを処理する必要があるQt APIサーバーの場合。 .. libuvライブラリがあります。
LibuvはNodeJS用に構築されていますが、Qtランドのファンは、デフォルトの選択メソッドの代わりに、epollsとkqueuesを利用できます。
Githubで詳細を確認してください https://github.com/supamii/QttpServer
QhttpServer は、必要なことを正確に行うようです。残念ながら、あまり活発ではないようです。
上記の単純なサーバーは、しばらくするとハングアップするため、MSwindowsオペレーティングシステムでの実行に問題がありました。これは、MSシステムでランダムに動作するwaitForReadyRead()が原因でした。次のwaitForReadyRead()プログラムは、readyRead()シグナルを使用するイベントループに置き換えられました。
# Project file
QT += core
QT += network
QT -= gui
TARGET = webServer
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
HEADERS += myhttpserver.h
//-----------myhttpserver.h--------------
#ifndef MYHTTPSERVER
#define MYHTTPSERVER
#include <QCoreApplication>
#include <iostream>
#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QIODevice>
class myHTTPserver : public QObject
{
Q_OBJECT
public:
explicit myHTTPserver(QObject *parent = 0);
~myHTTPserver();
QTcpSocket *socket ;
public slots:
void myConnection();
void txRx();
void closingClient();
private:
qint64 bytesAvailable() const;
QTcpServer *server;
};
#endif // MYHTTPSERVER
//------------------------ main.cpp ----------------------
#include "myhttpserver.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myHTTPserver server;
return a.exec();
}
myHTTPserver::myHTTPserver(QObject *parent) : QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()),this, SLOT(myConnection()));
if(!server->listen(QHostAddress::Any,8080))cout<< "\nWeb server could not start";
else cout<<"\nWeb server is waiting for a connection on port 8080";
}
void myHTTPserver::myConnection()
{
socket = server->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), this, SLOT(txRx()));
connect(socket, SIGNAL(disconnected()), this, SLOT(closingClient()));
}
void myHTTPserver::txRx()
{
char webBrowerRXData[1000];
int sv=socket->read(webBrowerRXData,1000);
cout<<"\nreading web browser data\n";
for(int i=0;i<sv;i++)cout<<webBrowerRXData[i];
cout<<"\n";
socket->write("HTTP/1.1 200 OK\r\n"); // \r needs to be before \n
socket->write("Content-Type: text/html\r\n");
socket->write("Connection: close\r\n");
socket->write("Refresh: 1\r\n"); //refreshes web browser every second. Require two \r\n.
socket->write("Pragma: no-cache\r\n");
socket->write("\r\n");
socket->write("<!DOCTYPE html>\r\n");
socket->write("<html><body>Number of seconds since connected.. ");
QByteArray str;
static qint16 count; //count number to be displayed on web browser
str.setNum(count++); //convert int to string
socket->write(str);
socket->disconnectFromHost();
}
void myHTTPserver::closingClient()
{
socket->deleteLater();
}
myHTTPserver::~myHTTPserver()
{
cout<<"\nclosing socket\n";
socket->close();
}
以下は、QML、pure-JS HTTP処理から使用できる単純なQtサーバーです。 https://github.com/ncp1402/ql-server