Ответ 1
Я нашел этот https://github.com/vinipsmaker/tufao, Его поздний ответ. Не уверен, что это помогает.
Я хотел бы написать небольшое приложение HTTP-сервера, которое получает запросы HTTP GET, обрабатывает их и отправляет ответ. Из-за истории приложения я бы предпочел использовать Qt для этого, но все, что я могу найти, это другое (более общее) направление: отправить запрос на сервер и получить ответ с помощью QNetworkAccessManager. Мне нужно что-то вроде сокета, который, когда приходит запрос, создает объект, где я могу выбрать url и т.д. Этого запроса, поэтому я могу отправить соответствующий ответ.
Я просто слепой или ничего подобного в рамках Qt? Если да, можете ли вы рекомендовать альтернативы?
Я нашел этот https://github.com/vinipsmaker/tufao, Его поздний ответ. Не уверен, что это помогает.
QtWebApp - это HTTP-сервер с поддержкой методов GET и POST, куки, сеансов и загрузки файлов. Использование этой библиотеки так же просто, как запись сервлета Java.
Веб-сайт проекта находится на немецком языке, однако загружаемые файлы находятся на английском языке, включая документацию.
Я только что выпустил первую версию QHttpEngine, которая направлена на восполнение пробела, который вы описали. Цель проекта - предоставить чрезвычайно простой набор классов, которые предоставляют HTTP-сервер, который интегрируется с Qt.
Например, чтобы обслуживать статические файлы из ресурсов в вашем приложении, все, что вам нужно сделать, это:
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
}
};
Пользователи могут затем отправить запрос POST на /doSomething
с параметрами, закодированными как JSON, и получить ответ, который генерирует слот.
Вся библиотека полностью документирована и поставляется с довольно исчерпывающим набором тестов. Он является кросс-платформенным и официально протестирован и поддерживается в Linux, Windows и Mac OS X. Существует по крайней мере одно крупное приложение с открытым исходным кодом, использующее QHttpEngine, NitroShare.
QttpServer= Qt + libuv + REST = ваш сервер API
Для сервера Qt API, которому необходимо обработать большое количество одновременных подключений, запрос и что- у вас... у нас есть библиотека libuv.
Хотя libuv построен для NodeJS, мы, поклонники Qt-land, по-прежнему можем использовать epolls и kqueues вместо метода выбора по умолчанию.
Подробнее о github https://github.com/supamii/QttpServer
QhttpServer, похоже, делает именно то, что вам нужно. к сожалению, это не кажется очень активным.
Вот простой Qt-сервер, который можно использовать с QML-обработкой HTTP-протокола pure-JS: https://github.com/ncp1402/ql-server
Вот простой HTTP-сервер HTTP, который будет обновлять количество секунд каждую секунду, поскольку соединение было сделано в веб-браузере. Он также отображает данные, отправленные веб-браузером на экране. Программа настроена на использование порта 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();
}
У вышеуказанного простого сервера были проблемы, запущенные в операционных системах MSwindows, так как он блокировал бы через некоторое время. Это связано с тем, что waitForReadyRead() работает случайным образом в системах MS. Программа ниже 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();
}