Web servers and application servers both offer a way to provide an embedded system with an Internet presence. The difference lies in the amount of programming required to adapt the server to the system. Classic web servers simply process HTTP requests and responses; anything else must be developed from scratch. Much of that work amounts to spending time and money "reinventing the wheel" for common functions and infrastructure that aren't supported by a web server.
By contrast, application servers include frameworks that dramatically shorten the development cycle. Choosing an application server means that you don't have to write commonly-used communication and user interface functions or their underlying infrastructure for each system. Programming resources can instead be focused on functionality that is specific to the system.
Using C/C++ for web development or a high level scripting language?
Since HTML is text based, a lot of work is required for: managing data, parsing requests, and assembling responses. All of this needs string manipulation. String manipulation in C isn’t rocket science, but it’s tedious and extremely easy to get wrong. Everything must be strictly typed, and memory must be explicitly reserved and released as needed, requiring scrupulous attention to every detail and making maintenance difficult.
On the other hand, with Web scripting environments such as Lua, much of this work has already been done. The application server abstracts the web server details, giving access to request and response objects and their associated APIs. This means that the application specific code has to deal only with high-level behavior and data.
A single line of script can implement the entire string concatenation. The lower-level machinations are automatically handled. Scripts also access and manipulate data without the need to worry about data organization or type definition.
Another important distinction is that scripting languages use just-in-time compilation while the system is operating. Whenever the user navigates or refreshes the browser, the virtual machine compiles any changed script before it sends the requested page to the browser, thereby automating the host of compilation, linking, and other developer overheads associated with an equivalent C-based application.
A typical web server has one role: to implement the HTTP protocol. This protocol activates a browser to issue a request that a server can respond to. Today’s web is highly sophisticated, featuring elaborate graphics and streaming media, yet surprisingly, the HTTP is a very simple protocol. All it does is transport requests and responses.
Because HTTP is a stateless protocol, there is no intelligence in the operation: no decision-making, no context, no scripts, and no code to execute. There is also no dynamic page creation to make user interfaces slick and easy to use. If a page needs to be dynamic, some other program has to do that work and put the result where the web server expects it to be.
POST is used to submit data from the web browser back to the server. This is the request that is generated when someone hits the "Submit" button on a filled-out form. A basic web server cannot process a POST request, since it will have no idea what to do with the data in the request. It must rely on some other program or utility to process the data.
On older standard websites, that utility might be a Common Gateway Interface (CGI) plug-in: the web server would simply hand any POST requests over to be handled by CGI. While CGI isn't appropriate for most embedded applications due to its size, performance, and inability to exist in a monolithic architecture, the fact remains that the web server needs something else to handle data returned by a web browser.
Most web-based applications need much more than this. In particular, embedded web applications generally must be able to let the web functionality affect the device operation - the remote browser has to be able to "talk" to the system. A web server has no such capability, so everything beyond the simple processing of HTTP must be written as a part of system development.
The low-level code that will interact directly with the system hardware will likely be written in C, and, because these routines are so system-specific, they will need to be written during development no matter how the web connectivity is implemented. The challenge is that a web server has no way of accessing those routines, meaning that some way of connecting the two must be built.
The two high-level elements that must be created are:
- A way for the web browser to invoke some other program;
- A program that can take an HTTP request and, from the request contents, invoke the appropriate C code.
These two functions sound deceptively simple. Conceptually, they are simple, but the details of what effectively amounts to a translation from a web conversation into device action are tedious and error-prone. Developers frequently underestimate the amount of time required to produce this code by a wide margin. For this reason, using only a basic web server will result in months of additional coding. You end up spending many weeks of time working on nitty-gritty details, things that an application server framework has already put in place.
Application servers provide that missing link, delivering configurable functionality that makes the connection between the simple HTTP operations and the complex matters the application needs to deal with. This low-level generic work is already done, and coding can focus on adapting the requests and responses to your specific technology.
Application servers build onto web servers a much broader range of configurable functionality. At the very least, they provide a way for the web server to hand off tasks to any of a variety of plug-ins that can handle requests for things other than simple resources. This means that an application server will allow real-time decision making and business logic, invoking other scripts or programs and, if appropriate, dynamically creating response pages in real time.
Most importantly for developers, however, is the fact that application servers tend to come with complete frameworks for use in developing code for the system. For example, if only a web server is used, then one must write custom code for recognizing and parsing requests and generating responses for functions being handled outside the web server. By contrast, the framework accompanying an application server will typically have a library that includes request and response objects. The low-level generic work is already done, and your coding can focus on adapting the requests and responses to your specific technology.
Each application server may provide a different set of resources targeted for its targeted programming environments and languages. While C is familiar to many systems engineers, and is generally better for low-level code, there are higher-level languages that simplify the programming and eliminate the need to handle numerous low-level details.
Real Time Logic's Barracuda Application Server is a good example of an application server designed specifically for use on deeply embedded systems. It supports the Lua scripting language and its associated Lua Server Pages, providing a dramatic speed-up in code development. You can learn more about Lua in the Lua Whitepaper.
It's Not Black and White
The differences outlined here between a web server and an application server apply in most cases, although, over time, the boundaries between the two have begun to blur. Typical basic web servers are more likely to focus on HTTP, while others may add a few features that were once associated only with application servers.
As an example, if all you need is a way to connect a web server to C/C++ functionality, the Barracuda Web Server provides web server capability and a C/C++ application framework for invoking C and C++ programs. While C programs (server business logic) take longer to develop and require that the server be taken down and restarted for updates (as opposed to Lua-based application server programs that are compiled on the fly), they do remain an option for embedded systems having limited web connectivity requirements.