readyRead() continous read from websites
-
I am reading two websites(REST-api) which update the data received from my hardware intermittently, and I plan to present them in a QTableView. I am able to read the data from the website only once even though I implemented a
while(reply->bytesAvailable())
in my code. I tried to run in debug mode and the program counter exits my SLOT implemented for readyRead() after the first read, I know there is no data for a few seconds but It wont read it again when there is new data on the website as it is outside the readyRead SLOT.
- Do i have to use a while(1) or for(;;) loop to read website continuously or implement a recursive timer that gets update from the website every now and then?
- if 'yes', do i implement it for each website with QNetworkAccessManger-Request/Reply, or for each websites readRead() SLOTs ?.
I plan to implement a tcp server connected to my application in the future and worry if the performance will go down, if 'reads' from the 'websites' and 'writes' to the DB is done within a continuous loop.
Can someone suggest me something (Thanks/appreciations in advance):
LogWindow::LogWindow(QWidget *parent) : QMainWindow(parent) { ui->setupUi(this); manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); QNetworkRequest request(web_url); reply = manager->get(request); connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); } void LogWindow::slotReadyRead() { while(reply->bytesAvailable()) { processWebsite1(); processWebsite2(); QStandardItem *firstCol = new QStandardItem(rf_ID); QStandardItem *secondCol = new QStandardItem(time); model->setItem(0,0,firstCol); model->setItem(0,1,secondCol); ui->logs->setModel(model); } emit datachanged(firstCol, secondCol); }
-
Hi @Muzab
Do i have to use a while(1) or for(;;) loop to read website continuously
No, that should not be necessary. Your slotReadyRead slot should be called repeatedly as you originally expected.
Where do you actually read from
LogWindow::reply
? Presumably inprocessWebsite1
orprocessWebsite2
? (If you're not actually reading, then that would explain why you don't get any subsequent readyRead signals).Also, just to help narrow things down, is your replyFinished slot being called? and if so, after what sort of period? ie immediately after slotReadyRead is called, or after some period of time? Can you use a packet sniffer like Wireshark to verify that that data is being sent by the server?
pc.
-
Thanks for the reply Paul.
How do I call my slotReadyRead repeatedly? can you give me an example?
You are right I am using
byteResponse = (QByteArray)reply->readAll();
in processWebsite1 and similar for processWebsite2. it reads the data but only once (should it be somewhere else?)
the replyFinished slot is immediately called after the readyRead() slot is serviced. I can try Wireshark , but what i have seen is that the website shows the latest data only on refresh. So it means that I need to refresh the website from my application?
-
You don't have to call slotReadyRead by yourself.
It is called as soon as there is something to read. -
@Muzab said:
the replyFinished slot is immediately called after the readyRead() slot is serviced.
That indicates that the HTTP request has completed - either because you manually closed the reply, or more likely, the server has.
readyRead() is not emitted recursively according to my understanding of the documentation.
From the QNetworkReply docs
Whenever more data is received from the network and processed, the readyRead() signal is emitted.
So readyRead should be emitted repeatedly, as long as the network reply (a single HTTP request) is still in progress.
I suspect that your website is not (as your current code is expecting) holding an HTTP session open, and streaming updates as they arrive - that would be unusual (albeit possible) behaviour for a web server.
If, instead, you need to do a new HTTP request periodically to get the updated sensor data (equivalent to refreshing the page in a web-browser), then you will need to use something like QTimer to invoke
manager->get(request);
periodically.but what i have seen is that the website shows the latest data only on refresh.
So if you visit the webpage in a browser, the page loads completely, showing the current data. Then, you need to refresh the page to see any updated data? If so, then yes, you will need to use QTimer (or equivalent) to "refresh" by issuing new new requests periodically.
A very rough example:
LogWindow::LogWindow(QWidget *parent) : QMainWindow(parent) { ui->setupUi(this); // Setup a network access manager. manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); // Setup a refresh timer. QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(refesh())); timer->start(5000); // Optionally, kick-off the first refresh immediately. refresh(); } LogWindow::refresh() { QNetworkRequest request(web_url); reply = manager->get(request); connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); }
Cheers.
-
@Paul-Colby said:
So if you visit the webpage in a browser, the page loads completely, showing the current data. Then, you need to refresh the page to see any updated data?
Thanks Paul. Timer seems to be a good solution as the webpage is dead until refreshed.