Server that executes RPC commands through HTTP.
Dependencies: EthernetInterface mbed-rpc mbed-rtos mbed
Import programHTTP-Server
Server that executes RPC commands through HTTP.
Overview
This program is a small HTTP Server that can execute RPC commands sent through HTTP and sends back a reply. This reply can be either a line of text or an HTML page.
HTTP Request
The server will only read the first line of the HTTP header. It does not check that the header is correct and it does not attempt to read the body. Hence, the server is only interested in the type of the request and the path. Instead of requesting a file, the path contains the RPC command.
RPC command encoding
Information
The RPC command must be encoded in a special way because no spaces are allowed in the path.
Thus, the RPC command is encoded in this way :
/<obj name or type>/<func name>?arg1_name=arg1_val&arg2_name=arg2_val
or, if the RPC command does not have any arguments :
/<obj name or type>/<func name>
So, a complete URL might be :
http://10.2.200.116/led2/write?val=1
The name of the arguments does not appear in the final RPC command. So these 3 urls will do exactly the same thing :
http://10.2.200.116/led2/write?val=1 http://10.2.200.116/led2/write?test=1 http://10.2.200.116/led2/write?blabla=1
Also, the order of the arguments are preserved.
Request handlers
To process requests, the server relies on RequestHandler. Each RequestHandler is assigned to a request type. Each type of request is assigned to a certain role :
- PUT requests to create new objects
- DELETE requests to delete objects
- GET requests to call a function of an object
However, there is a RequestHandler that accepts only GET requests but it can create/delete/call a function. This was necessary to provide an interactive web page that allows creation and deletion of objects.
Reply
The reply depends on the formatter. Currently, three formatters are available :
- The most basic one does not modify the RPC reply. Hence, if you consider sending request from python scripts, this formatter is the most appropriate one.
- A simple HTML formatter will allow the user to view the RPC reply and a list of RPC objects currently alive from a browser.
- Finally, a more complex HTML formatter creates an entire web page where the user can create and delete an object as well as calling functions on these objects.
Configure the server
The configuration of the server consists on choosing the formatter and adding one or more request handlers to the server. The main function initializes the server in order to produce HTML code and to receive data only using GET requests. If you want to use a simpler and different version of the server you can change the content of the main function (located in main.cpp) by this code :
main
RPCType::instance().register_types(); EthernetInterface eth; eth.init(); eth.connect(); printf("IP Address is %s\n", eth.getIPAddress()); HTTPServer srv = create_simple_server(); if(!srv.init(SERVER_PORT)) { printf("Error while initializing the server\n"); eth.disconnect(); return -1; } srv.run(); return 0;
However, this configuration will not work with the following examples.
Examples
I assume that the server is using the InteractiveHTMLFormatter (which should be the case if you did not make any changes).
Using a browser
Here is a quick guide how to run this program :
- Compiles this program and copies it to the mbed
- Open TeraTerm (install it if you don't have it), select serial and choose the port named "mbed Serial Port"
- Reset your mbed
- The IP address should appear in teraterm. In this example, I will use 10.2.200.116.
- Open your browser and go to http://10.2.200.116/.
- If everything is ok, you should see a webpage.
Now, let's switch on a led. First, we need to create an object to control a led :
Then, let's write an RPC command to switch on led :
Using python
This program creates and switches on led2.
Sending RPC commands over HTTP with Python
import httplib SERVER_ADDRESS = '10.2.200.38' h = httplib.HTTPConnection(SERVER_ADDRESS) h.request("GET", "/DigitalOut/new?arg=LED2&name=led2") r = h.getresponse() print r.read() h.request("GET", "/led2/write?arg=1") r = h.getresponse() print r.read() h.close()
Of course, you might have to change the server address in order to make it work.
Files at revision 10:8b4c3d605bf0
Name | Size | Actions |
---|---|---|
[up] | ||
EthernetInterface.lib | 65 | Revisions Annotate |
Formatter.cpp | 4819 | Revisions Annotate |
Formatter.h | 775 | Revisions Annotate |
HTTPServer.cpp | 2861 | Revisions Annotate |
HTTPServer.h | 791 | Revisions Annotate |
RPCCommand.cpp | 2453 | Revisions Annotate |
RPCCommand.h | 595 | Revisions Annotate |
RPCObjectManager.cpp | 1410 | Revisions Annotate |
RPCObjectManager.h | 589 | Revisions Annotate |
RPCType.cpp | 1246 | Revisions Annotate |
RPCType.h | 341 | Revisions Annotate |
RequestHandler.cpp | 3296 | Revisions Annotate |
RequestHandler.h | 977 | Revisions Annotate |
main.cpp | 1286 | Revisions Annotate |
mbed-rpc.lib | 64 | Revisions Annotate |
mbed-rtos.lib | 65 | Revisions Annotate |
mbed.bld | 65 | Revisions Annotate |