IoT-Enabled Embedded Web Server Reference Example
Embedded HTTP and WebSocket servers have been designed specifically for tiny microcontrollers with limited resources.
Join the DZone community and get the full member experience.
Join For FreeWe recently committed our Embedded HTTP and WebSocket Server to GitHub. The Embedded HTTP and WebSocket server, called the Minnow Server, has been specifically designed for tiny microcontrollers with limited resources.
Here’s the interesting part…
We also included a reference example that shows how to build a modern real-time web user interface for device management. The web application is a so-called Single-Page Application (SPA). The SPA is initially loaded into the browser by using one HTTP GET request. From this point on, the WebSocket protocol is exclusively used for all interaction. Messages are exchanged as JSON and binary message.
The reference example includes real-time updates of LEDs and a thermostat gauge, and it shows how to do firmware upload over WebSockets. But that’s not all. The example can also be IoT enabled; we will get more into how that works later...
So what’s the big deal?
In my previous article, Rethinking Web-Based Device Management, I explained how one could use a framework such as Vue.js and WebSockets as a base for creating a modern reactive device management application. However, a resource-constrained microcontroller simply does not have the space to store a web application based on a framework such as Vue.js. The flash memory for the typical microcontroller, such as an ARM Cortex M3, provides insufficient storage for the typical modern web application.
We have now designed a microcontroller friendly reusable SPA reference example that requires very little storage space in the device. The complete SPA, including all resources such as images, CSS, and JavaScript, when compressed using our online HTML amalgamator service, requires only 41 Kbytes of flash memory storage space!!!
Designed to help you get up and running fast...
The reference example, designed for educational purposes, includes ready-to-use build environments for Windows and Linux. On Linux, you can build a ready to use web server executable as follows:
make packwww minnow
The above make command amalgamates and compresses all HTML resources before compiling all code. The HTML resources are embedded inside the executable, thus after starting the executable, simply navigate to http://localhost.
Now, this is important…
The Single Page Application (SPA) has been designed so that it can easily be reused for your own embedded device management application. The CSS and HTML5 building blocks in this application have been designed for reuse. In addition, the WebSocket communication JavaScript library included in the example is generic and can easily be reused in other applications.
The Reusable SPA Reference Example
The Single Page Application reference example includes several web pages, but unlike a traditional web application, no page is loaded when clicking a link in the navigation menu. Instead, all pages reside in one HTML file, and JavaScript is used to hide and show DIV elements (the pages) when navigating the menu.
We also have a number of modal dialog boxes. The first modal dialog box is shown as soon as the SPA has been loaded into the browser.
Figure 1: The modal login dialog
A headless device (a device without a native display) requires default credentials. The hardcoded default credentials are "root" and "password." A recommendation is to set up a device production environment that can provide unique default credentials for each produced device and to also force the user to set new credentials at the first login.
A cool feature:
From Figure 1, you can see that we use non-encrypted communication. The Minnow Server can be used with or without TLS. A cool feature we have added is that the login is safe even when used without TLS. The password is hashed with a seed value provided by the server, a so-called nonce, before sent to the server. Details on the secure hash based authentication can be found in the Minnow Server Reference Platform Specification.
The following page is presented after logging in:
Figure 2: AJAX powered calculator
You probably wonder why we have a calculator in a device management reference design. We previously published an article on how to run AJAX over WebSockets and the included example provided math AJAX services. However, the AJAX math backend services were not designed for the Minnow Server and C code. We wanted to include the AJAX math services in this design because...
WebSockets vs. AJAX
WebSockets can handle multiple bidirectional messages between the browser and the server. There is no correlation between the messages sent in either direction. It is up to the application to interpret and manage these messages. However, it is many times useful to use a request/response design pattern in web applications, where a JavaScript callback is called when the response is returned from the server. Many web developers are accustomed to AJAX and the calculator shows how to use AJAX in JavaScript and in C code. The math operations are performed on the server side and each math operation request sent to the server is followed by a math response sent to the browser. The result is displayed in the calculator when the response returns. AJAX also includes a success/error (try/catch) concept. Try dividing a number by zero and see what happens.
So now, you see why we wanted to include AJAX. We recommend reading our previous article AJAX over WebSockets, so you get the full picture on how AJAX over the WebSocket protocol works. Note that the included AJAX over WebSockets JavaScript library provides a Promise API.
Figure 3: LED device management page
Most devices include LEDs; thus, the server LED logic can easily be ported to most devices. Clicking an LED button sends a real-time event to the server, which sets the LED. The server then sends an updated LED message to the browser.
It's all real-time and asynchronous...
In Figure 3, we run the server in a Windows console window. The LED state is printed to the console. You can also set the LED state in the console (on the server side) by using the keyboard letters B to E. The server will then send a real-time update message to the browser.
Figure 4: Device to browser real-time data
Although the LED page shows how to send real-time data from the server to the browser, the thermostat was included as an additional real-time event example. The up and down keyboard arrow keys control the temperature.
Real-time HTML5/canvas widget, but there’s just one problem…
We used a freely available gauge widget library for the thermometer layout. You may send real-time data from the server to the browser by keeping the up or down arrow key pressed. The keyboard events are sent in real time to the browser, which, in turn, updates the thermometer widget. However, the irony is that the thermometer widget is unable to handle large amounts of incoming data. The lesson learned from this is that not all free widget libraries can handle large amounts of data.
Figure 5: Drag and drop firmware upload
The firmware upload page shows how to create an HTML 5 drag and drop upload page and how to send the uploaded file to the server via the WebSocket connection.
Binary or JSON...
All messages sent via the WebSocket connection are sent as JSON text messages except for the upload, which is sent as binary data. Modern JavaScript can easily manage binary data and the WebSocket protocol supports both binary and text frames.
Figure 6: Set new credentials
The credentials page lets the user update his/her credentials. Unlike the secure login page, setting new credentials is not safe unless TLS is used. It is simply not possible to protect the credentials from being eavesdropped without using TLS. The good thing is that the Minnow Server can be TLS enabled.
IoT Enabling the SPA Reference Example
Devices with an embedded web server are typically installed and operated on private networks behind company firewalls and/or routers. Devices deployed behind private networks are automatically protected from outside use and abuse. However, such deployments also prevent legitimate remote use.
Easy and secure external access:
Sometimes, embedded devices need to be operated from a remote location via the Internet, and the safest way to do this is to IoT enable the device and have the device connect to a server on the Internet. The following figure depicts such a setup.
Figure 7: Access the embedded device locally or via the Internet
The Minnow Server reference example includes an optional IoT component that can be enabled at compile time. Note that this component is disabled by default.
Online Message Broker:
An online server acts as a proxy between the remote user and device. When the device is running in IoT mode, the device operates as a network client. As you probably already know, network clients typically do not need any network configuration for connecting out to services on the Internet.
Easy Online DIY Broker Solution:
The online server is not ready to use service and is instead set up as a private IoT server. The Minnow Server reference platform also includes the required IoT server code and instructions for setting up a private online server. The benefit with a privately owned IoT server is that you are not dependent on any particular IoT service provider. You will be surprised to find out how easy and reasonable it is to operate a private IoT server.
TLS-Enabled Embedded Web Server
In all the examples above, we have been running the Minnow Server in non-secure mode. That means an eavesdropper can snoop on all traffic exchanged between the browser and the server. To prevent eavesdropping and secure the "Set new credentials page" (Figure 6), TLS must be used.
Secure WebSockets (YES), HTTPS (NO)
The Minnow Server can be TLS enabled, and this is where a WebSocket server shines compared to using a standard web server. You may already be using an embedded web server in your microcontroller powered device, but TLS enabling a standard web server for a resource-constrained device typically ends in disaster. To understand why TLS creates such a problem for standard web server technology, see our tutorial When Not to Embed a Web Server in a Device.
ESP8266, FreeRTOS, and lwIP
The Minnow Server and the reference platform can be compiled for any microcontroller. The Minnow Server includes porting layers for many RTOS's and TCP/IP stacks.
The GitHub example code includes a ready to run ESP8266 build environment. The low cost ESP8266 WiFi chip is great for learning purposes. The following video shows how to use the ready to use web based IDE for compiling and uploading the firmware to an ESP8266. The video also shows how to set up the IoT bridge.
Limitations
The Minnow Server is primarily designed for small resource constrained systems. Although the Minnow Server can be set up to manage several connections, the reference example is designed to conserve RAM memory and is set up to manage one connection at a time. Attempting to connect a new browser window while another browser window is using the one and only WebSocket connection will not work. If you are an embedded developer not limited by a resource-constrained microcontroller solution, consider using a more powerful embedded web server such as the Barracuda App Server, which also includes WebSockets.
Opinions expressed by DZone contributors are their own.
Comments