-
Notifications
You must be signed in to change notification settings - Fork 0
Hello Browser
This example shows you the shortest code possible to sanely start a full HTTP server with the Network module and deliver a simple 'Hello World' to requests.
The Network module ships with a HTTP server meant to make it trivial to implement HTTP based APIs when using the Nuria Framework.
- HttpServer - Without the server no one accepts requests
- HttpNode - The middleware between the protocol and the user logic
- HttpClient - QIODevice which lets you interact with the client
- Callback - Functor object, like std::function, but generic.
Tip: Click on one of the classes above to get to their documentation
First, we will set up a new project. Also add the 'network' module to your project file: NURIA += network
. You can find the complete file here
Next, open main.cpp. Include the files httpclient.hpp
, httpserver.hpp
and httpserver.hpp
- All of these can be found in nuria/
.
We can now add the first important thing: The actual server object. HttpServer will provide us with a stand-alone HTTP server which uses TCP for connections. Just instantiate it on the stack: Ref 1
Now add the method which we want to be called when a request is made. In Ref 2 we simply called the static method mySlot
.
This mySlot
method is a usual C++ method, and it could be anything we can call. See Callback for further information.
So, when HttpNode wants to invoke a method to deal with a request, it will pass the HttpClient
instance representing the requesting client to it. HttpClient is a QIODevice. Reading from it will give you the POST body data (If any). Writing to it will send a response to it. Don't worry, sending the HTTP header will be taken care of for your :)
So, back to mySlot
. With the HttpClient in our hands, we can send the client a warm welcome. Using HttpClient::write(), send a short HTML message:
client->write ("<h1>Hello world</h>");
And that's everything we need to do in there. Next we need to actually tell the server about mySlot
.
Head back into the main()
and have a look at reference 3. This may look confusing at first,
where does this node()
stuff come from? The server has what we call a root node. Nodes can contain sub-nodes. This is Nurias way to express paths. Each node acts like a virtual directory.
So, instead of putting (lets say) a PHP script into a directory, you put a method into a node for the server to find it later. The root node is the first node which will be asked to handle a request. If it sees that it can't directly do so, it will ask one of its child nodes whose name matches the one in the requested path to handle it. This way, requests are propagated through a chain of nodes. If you want to know more, I suggest you to read HttpNodes documentation.
After this long explanation, all we want to do is to connect
(connect comes frome the Qt terminology) our mySlot
method to the node, so that when the special index
page is requested, it will be called to serve some content to the client. Think of index
as equivalent to files like index.php
in Apache. So, we write: server.root ()->connectSlot ("index", mySlot);
- The first argument is the name under which a client can request, I mean, invoke our method, and the second one is the method itself. See Callbacks documentation what you could pass instead if you want to know - Like for example a C++11 lambda!
Okay, we're all set now to tell the server to begin accepting connections. In reference 4 we tell it do listen on port 8080
(Port 80
would require system administration permissions - Which we don't have) on all interfaces (Thus, another computer in the network could also do this). The example code adds a little logging here to tell you if it worked or not which is a good practice to do.
Still with me? Now, just tell your IDE to compile and run the example. If you're in a shell in the example directory, you can run qmake && make && ./HelloBrowser
to do just that. Worked? Great. Now, just go to http://127.0.0.1:8080/ and be welcomed by your application!
I suggest to toy around a bit. Like add a second slot like we did, but use Callback::fromLambda
to call a lambda instead. If that new slot is connected to test
, then the URL to it will be http://127.0.0.1:8080/test
That's it, thanks for reading.