Proccessing long pull requests [i'm crying]
-
We need to realize web-server using c++(qt).
Our server get requests from client and push all descriptors into Queue. We proccess this Queue in four threads.
But we use two types of requests, one of them long pull requsts, other fast requests.
When we get four long pull requests in the threads, server is blocking for other fast requests.How we can solve this problem?
-
How did you organise server side threads?
-
without any source code, it is difficult to find the error.
Can you please post your server code (or part of them)?And please: Don't cry :)
-
//webserver1.cpp
@
#include "webserver1.h"
#include "requesthandler1.h"
#include <QCoreApplication>
#include <QtConcurrentRun>
#include <QTime>WebServer1::WebServer1(QObject *parent) :
QTcpServer(parent)
{
QtConcurrent::run(this, &WebServer1::processQueue);
}void WebServer1::incomingConnection(int socketDescriptor)
{
sockets.append(socketDescriptor);
}void WebServer1::processQueue()
{
while (true) {
if (!sockets.isEmpty() && RequestHandler1::semaphore->tryAcquire()) {
RequestHandler1 *handler = new RequestHandler1(sockets.takeFirst());
connect(handler, SIGNAL(finished()), handler, SLOT(deleteLater()));
handler->start();
} else {
usleep(1000);
}
}
}
@@
#include "requesthandler1.h"
#include "httpserver.h"
#include <QtNetwork>
#include <QtGlobal>QSemaphore *RequestHandler1::semaphore = new QSemaphore (4);
QSemaphore *RequestHandler1::semaphoreLongPull = new QSemaphore (2);RequestHandler1::RequestHandler1(int socketDescriptor, QObject *parent) :
QThread(parent), socketDescriptor(socketDescriptor)
{
}void RequestHandler1::run()
{
QTcpSocket *tcpSocket = new QTcpSocket;
if (!tcpSocket->setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket->error());
return;
}
if (!tcpSocket->bytesAvailable()) {
tcpSocket->waitForReadyRead();
}
QString header = "";
bool flag = false;
int i = 0;
while (tcpSocket->canReadLine()) {
i++;
header += tcpSocket->readLine();
if (header.split(" ", QString::SkipEmptyParts).at(1) == "/test/" && i==1)
{
int descriptor = socketDescriptor;
test(header.split(" ", QString::SkipEmptyParts).at(1), descriptor);
flag = true;
}
}
if (!flag) {
qDebug()<<"not looong";
tcpSocket->write(QString("HTTP/1->0 200 Ok\r\n"
"Content-Type: text/html; charset="utf-8"\r\n"
"\r\n"
"<h1>" + QString::fromUtf8("Привет, мокапщик") + "</h1>\n"
+ QDateTime::currentDateTime().toString() + "\n").toUtf8());
if (tcpSocket->bytesToWrite()) {
tcpSocket->waitForBytesWritten();
}
}
tcpSocket->close();
delete tcpSocket;
semaphore->release();
}void RequestHandler1::test (QString link, int descriptor){
qDebug() <<"it was so loooong";
QTcpSocket * tcpSocket = new QTcpSocket;
tcpSocket->setSocketDescriptor(descriptor);
tcpSocket->write("get mockup", strlen("get mockup"));
tcpSocket->waitForBytesWritten();
usleep(1000000);
qDebug() <<"doooone";
}
@ -
I can't read headers and indicate request without opening socket, but when i open many sockets PIPes are ending.
-
Then i recomend you:
"video":http://voidrealms.com/viewtutorial.aspx?id=39
"source code":http://voidrealms.com/downloadtutorial.aspx?id=39
this solution tested and it works fine. -
bq. this solution tested and it works fine.
how we can implement long-pull requests handling?
my problem stay online soo -
Is there a reason you limit yourself to 4 threads? I think I/O is going to be the blocking factor, not processing...
Would it be feasible to reserve one thread for your short requests?
-
[quote author="Andre" date="1361204431"]Is there a reason you limit yourself to 4 threads? I think I/O is going to be the blocking factor, not processing...
Would it be feasible to reserve one thread for your short requests?[/quote]
Yep, we test it with ab (-c 1000) and look that 4 help us to keep PIP's count and productivity on level (of, course it'll be customize in future).
We know is this long poll or short request only when we read headers, for this operation we need to initialize socket with request descriptor, but when we close socket connection lost (or we must to process this request).
Could we can reopen socket with the same descriptor, or how we can save number of PIPs?
-
Maybe i misunderstood you but from the link which i given you can find code where new thread created not for each socket but for a incoming data and once connected sockets are present in your list until not closed.