Networking

HTTP

In Cascades, networking APIs are provided by the QtNetwork module. This module exposes a mix of low-level and high-level APIs used for sending and receiving data over the network. For common network operations, there are high-level APIs for HTTP and FTP communication. For lower-level operations, you can use the APIs for TCP and UDP communication.

Flow diagram showing the interaction between the high-level APIs

Basic HTTP communication is handled using the Network Access API, which has three core classes: QNetworkRequest, QNetworkAccessManager, and QNetworkReply.

QNetworkRequest represents an HTTP request. At a minimum, it must contain a URL for the destination. The request can also contain HTTP headers and SSL options.

The QNetworkRequest API

QNetworkAccessManager receives network requests, and sends them over the network using one of its HTTP request functions (get(), post(), put(), etc) which return a QNetworkReply. These functions are all asynchronous in nature, so they won't block your main application thread.

QNetworkAccessManager also contains functionality for cookie handling, caching, and proxy handling.

The QNetworkAccessManager API

QNetworkReply represents an HTTP reply. Among other things, it contains reply data from the destination URL, HTTP headers consisting of the status code, and any errors. Data in a QNetworkReply is reported asynchronously, so you can connect to its signals and handle information as it arrives.

The readyRead() signal is triggered whenever new data arrives over the network. You should subscribe to this signal if you want to parse data as it arrives, even if you're not finished with the reply. The finished() signal is triggered once an HTTP request is complete.

The QNetworkReply API

Here's an example that demonstrates how to send an HTTP GET request and receive the result. The first step is to create the network request and set the destination URL.

// Creates the network request and sets the destination URL.
QNetworkRequest request = QNetworkRequest();
request.setUrl(QUrl("http://www.blackberry.com"));

Next, you create the network access manager, connect a custom slot for handling the reply to its finished() signal, and send the request. In this example, an HTTP GET request is sent.

// Creates the network access manager and connects a custom slot to its
// finished signal. Checks the return value for errors. 
QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(this);
connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)),
        this, SLOT(requestFinished(QNetworkReply*)));

// Sends the HTTP request.
networkAccessManager->get(request);

Within the requestFinished() slot, you process the reply data and call deleteLater() to delete the data when you're done with it.

void ApplicationUI::requestFinished(QNetworkReply* reply)
{
	myActivityIndicator->stop();
	myLabel->setVisible(false);

	// Check the network reply for errors.
	if (reply->error() == QNetworkReply::NoError)
	{
		// Open the file and print an error if the 
        // file cannot be opened.
		if (!myFile->open(QIODevice::ReadWrite))
		{
			// The file failed to open.
			return;
		}

		// Write to the file using the reply data and close the file.
		myFile->write(reply->readAll());
		myFile->flush();
		myFile->close();

		// Create the data model using the contents of the file.
		XmlDataModel *dataModel = new XmlDataModel();
		dataModel->setSource(
            QUrl("file://" + QDir::homePath() + "/model.xml"));

		// Set the new data model on the list.
		myListView->setDataModel(dataModel);
	}
	else
	{
		// Problem with the network.
	}

    // Deletes the reply the next time
    // the event loop is entered.
	reply->deleteLater();
}

Last modified: 2013-04-30