2010-06-26 30 views
19

Me gustaría escribir una pequeña aplicación de servidor HTTP que recibe solicitudes HTTP GET, las procesa y envía una respuesta. Debido a la historia de la aplicación, preferiría usar Qt para esto, pero todo lo que puedo encontrar es la otra dirección (más común): enviar una solicitud a un servidor y recibir una respuesta usando QNetworkAccessManager. Lo que necesito es algo así como un socket que, cuando llega una solicitud, produce un objeto donde puedo elegir url, etc. de esta solicitud, para que pueda enviar una respuesta adecuada.Qt Servidor HTTP?

¿Estoy solo ciego o no hay nada como esto en el marco de Qt? Si es así, ¿puedes recomendar alternativas?

Respuesta

11

He encontrado https://github.com/vinipsmaker/tufao, Es una respuesta tardía ... no estoy seguro de si ayuda.

+0

En realidad, es tarde, pero este proyecto parece ser lo que estaba buscando en ese momento. – grefab

14

QtWebApp es un servidor HTTP con soporte de método GET y POST, cookies, sesiones y cargas de archivos. Usar esta biblioteca es tan simple como escribir un Servlet de Java.

El sitio web del proyecto está en alemán, sin embargo, los archivos descargables están en inglés, incluida la documentación.

+3

uno de los buenos, usando esto para servicios web: http://stackoverflow.com/questions/11558237/creating-simple-webservice-in-c-qt-acting-as-server- providing-json-data? lq = 1 –

+0

sí, muy agradable y fácil de modificar para proyectos propios. – Zeks

3

QhttpServer parece hacer exactamente lo que necesita. desafortunadamente no parece ser muy activo.

12

Me acaban de publicar la primera versión de QHttpEngine, que tiene como objetivo llenar el vacío que usted ha descrito. El objetivo del proyecto es proporcionar un conjunto extremadamente simple de clases que proporcionen un servidor HTTP que se integre con Qt.

Por ejemplo, para servir archivos estáticos de recursos en su aplicación, todo lo que tendría que hacer es:

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

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

También puede crear una clase derivada de QObject que exponen sus ranuras como criterios de valoración en un HTTP API. Por ejemplo:

class ApiHandler : public QObjectHandler 
{ 
    Q_OBJECT 

private slots: 

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

continuación, los usuarios pueden enviar una solicitud POST a /doSomething con los parámetros codificados como JSON y recibir la respuesta de que la ranura genera.

Toda la biblioteca está completamente documentada y viene con un conjunto de pruebas bastante exhaustivo. Es multiplataforma y está oficialmente probado y admitido en Linux, Windows y Mac OS X. Existe al menos una aplicación de código abierto principal que utiliza QHttpEngine, NitroShare.

2

Aquí hay un servidor web HTTP muy simple que actualizará la cantidad de segundos, cada segundo, desde que se realizó una conexión en el navegador web. También muestra los datos enviados por el navegador web en la pantalla. El programa está configurado para utilizar el puerto 8080 por ejemplo 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(); 
} 
0

El servidor sencilla anterior tenía problemas que se ejecutan en sistemas operativos mswindows ya que bloqueará después de un tiempo. Esto se debió a que waitForReadyRead() funcionaba de forma aleatoria en los sistemas MS. El programa debajo de waitForReadyRead() fue reemplazado por un bucle de evento usando la señal 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(); 
} 
6

QttpServer = Qt + libuv + = REST API su servidor

Para un servidor de la API de Qt que necesitan para manejar una large number of concurrent connections, solicitud, y lo que usted quiera ... que tenemos el biblioteca libuv.

Aunque libuv está diseñado para NodeJS, los seguidores de Qt-land aún pueden beneficiarse de epolls y kqueues en lugar del método de selección predeterminado.

Ver más en github https://github.com/supamii/QttpServer

+0

Esa es la mejor respuesta aquí ... después de investigar una serie de soluciones. Esta solución es simple, basada en la tecnología correcta + ejemplos claros y simples. Voy a probarlo ahora ... – rubmz