web-dev-qa-db-fra.com

Serveur HTTP Qt?

Je voudrais écrire une petite application serveur HTTP qui reçoit les requêtes HTTP GET, les traite et envoie une réponse. En raison de l'historique de l'application, je préférerais utiliser Qt pour cela, mais tout ce que je peux trouver est l'autre direction (plus courante): envoyer une demande à un serveur et recevoir une réponse en utilisant QNetworkAccessManager . Ce dont j'ai besoin est quelque chose comme une socket qui, quand une demande arrive, produit un objet où je peux choisir l'url, etc. de cette demande, afin que je puisse envoyer une réponse appropriée.

Suis-je simplement aveugle ou rien de tel dans le cadre Qt? Si oui, pouvez-vous recommander des alternatives?

23
grefab

J'ai trouvé cela https://github.com/vinipsmaker/tufao , c'est une réponse tardive .. je ne sais pas si cela aide.

13
Anand Rathi

QtWebApp est un serveur HTTP prenant en charge GET et POST, cookies, sessions et téléchargements de fichiers. L'utilisation de cette bibliothèque est aussi simple que d'écrire un Java.

Le site Web du projet est en allemand, mais les fichiers téléchargeables sont tous en anglais, y compris la documentation.

15
Stefan

Je viens de publier la première version de QHttpEngine , qui vise à combler le vide que vous avez décrit. Le but du projet est de fournir un ensemble extrêmement simple de classes qui fournissent un serveur HTTP qui s'intègre à Qt.

Par exemple, pour servir des fichiers statiques à partir de ressources dans votre application, il vous suffit de:

QFilesystemHandler handler(":/www");
QHttpServer server(&handler);

server.listen(QHostAddress::LocalHost, 8000);

Vous pouvez également créer une classe dérivée de QObject qui expose ses emplacements en tant que points de terminaison dans une API HTTP. Par exemple:

class ApiHandler : public QObjectHandler
{
    Q_OBJECT

private slots:

    QVariantMap doSomething(const QVariantMap &params) {
        // do something with the parameters and return a response
    }
};

Les utilisateurs peuvent ensuite envoyer une demande POST à /doSomething avec les paramètres encodés en JSON et reçoit la réponse générée par le slot.

La bibliothèque entière est entièrement documentée et est livrée avec une suite de tests assez complète. Il est multiplateforme et est officiellement testé et pris en charge sur Linux, Windows et Mac OS X. Il existe au moins une application open source majeure utilisant QHttpEngine, NitroShare .

14
Nathan Osman

Voici un serveur Web HTTP très simple qui mettra à jour le nombre de secondes, chaque seconde, depuis qu'une connexion a été établie sur le navigateur Web. Il affiche également à l'écran les données envoyées par le navigateur Web. Le programme est configuré pour utiliser le port 8080, par exemple 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();
}
8
vk3who

QttpServer = Qt + libuv + REST = votre serveur API

Pour un serveur Qt API qui doit gérer un grand nombre de connexions simultanées , une demande et ce que vous avez. .. nous avons la bibliothèque libuv.

Bien que libuv soit conçu pour NodeJS, nous, les fans de Qt-land, pouvons toujours bénéficier d'epolls et de kqueues au lieu de la méthode de sélection par défaut.

En savoir plus sur github https://github.com/supamii/QttpServer

7
Huy

QhttpServer semble faire exactement ce dont vous avez besoin. malheureusement, il ne semble pas être très actif.

3
Pierre Rust

Le serveur simple ci-dessus avait des problèmes de fonctionnement sur les systèmes d'exploitation MSwindows car il se bloquait après un certain temps. Cela était dû au fait que waitForReadyRead () fonctionnait de manière aléatoire sur les systèmes MS. Le programme ci-dessous waitForReadyRead () a été remplacé par une boucle d'événement utilisant le signal 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();
}
2
vk3who

Voici un serveur Qt simple qui peut être utilisé à partir du traitement HTTP QML pur JS: https://github.com/ncp1402/ql-server

2
user2053898