Web of Things Framework: An Architectural Overview

This article describes the core design of WoT.City Web of Things framework. The Web of Things framework from WoT.City has been developing a reference design.

Figure 1-1: Layers of WoT.City Framework Figure 1-1: Layers of WoT.City Framework

The overall view of the whole framework is divided into two parts. One is the frontend, and the other one is the backend. You can treat WoT.City WoT framework as a full stack WoT framework.

The backend consists of WoT servers. The instance of a WoT server is a running process. A WoT server could be installed at a physical deivce. However, when the device has limited hardware resources, called constrained device, a WoT server should be deployed as a broker server.

In a short, there are two WoT server models of WoT.City WoT framework.

  1. Device Server Model. As shown in figure 1-2.
  2. Broker Server Model. As shown in figure 1-3.

Figure 1-2: WoT.City Framework as Device Server Figure 1-2: WoT.City Framework as Device Server

Figure 1-2 shows the model of device server. In practice, this means that there is a WoT.City WoT server process running on a physical device.

Figure 1-3: WoT.City Framework as Broker Server Figure 1-3: WoT.City Framework as Broker Server

Figure 1-3 shows the other model called broker server. In practice, this means that a physical device is behind a broker server. And the physical device is sending data to a broker server over the web. The broker server is then forwarding the data to user clients.

WoT.City WoT framework is combined with these two models.

Thing Object

A Web of Things framework is designed to work with Thing Objects. And there are two types of a thing object.

  • Physical Object in its name is to represent a physical IoT device.
  • Virtual Object is a proxy of physical object. In other case, a virtual object can represents a virtual hardware (aka virtual device, fake hardware, etc).

A Internet of Thing device is represented as a physical object in the Web of Things framework. This design comes out the name Thing Object. In general, a thing object is described and published to the web by JSON or JSON-LD.

General WoT Framework

A Web of Things framework is a different idea from a legacy software framework. A Web of Things framework should be fullstack. Through WoT.City open source project, I'm going to develop a fullstack Web of Things framework. The project name of this framework is called WoT.City. It's open source and please fork WoT.City at Github.

https://github.com/wotcity/dotcity-wot-framework  

This article will go through the design progress of WoT.City WoT framework. And it also demonstrates the usage of web technologies to architect a Web of Things framework. WoT is a shorthand for connecting IoT devices over the web. So one of the most important resource among a WoT framework is W3C WoT. Please take W3C WoT open source project to your core reference.

https://github.com/w3c/web-of-things-framework  

The layer of application procotols (for example HTTP/WebSocket/CoAP) makes having a homogeneous architecture and somewhat easiler to design for. So that, WoT.City WoT framework does not have any conflicts with W3C WoT or other 3rd party's.

In some use cases, WoT.City can have a homogeneous software integration with W3C WoT.

Common Design

WoT.City WoT framework is a fullstack framework design. This means that it combines with both of the frontend stacks and backend stacks. There are two layers of the backend design of WoT.City WoT Framework.

  • Things Service Layer is the upper layer which contains the various server use case implementations. For example, WebSocket servers and HTTP servers. Each server is also divided into several sub-implementations according to their use cases. The first server implementation in the upper layer is Websocket Broker Server.

  • Things Data Layer is the bottom layer that it manages thing objects. Thing object could be described in JSON or JSON-LD.

In general case, the most important feature of a Web of Things Framework is Data Composition Layer. The first layer of the fronted part is it.

  • Composition Layer is the data compositor. Please see apps/moving-line for a complete example.

The composition layer is not the only main feature of a common Web of Things Framework. The Web of Things is the application layer of Internet of Things. Some of the other features of the application layer includes Findability Layer, Sharing Layer, Findability Layer and Accessibility Layer.

Web of Things is a set of best practices that I will describe them according to the different layers of Web of Things architecture 1.

Accessibility

Accessibility is at the Thing Service Layer.

In my opinion, the accessibility layer should be a set of server implementations. This means that there are different use cases, and each has its corresponding server implementation. There is an example of server implementation called WebSocket Broker Server in WoT.City WoT Framework. This server is specially to implement the use cases, as show in the following:

  1. For a constrained IoT device which has less memory and limited computing power.
  2. Microcontrollers (MCUs) is the type of constrained devices.
  3. For a constrained device sending data streams (time-series data) to the web.

I will introduce WebSocket Broker Server and its usage in a bit before hacking the code.

WebSocket Broker Server

The most common and suggested use case of a Web of Things framework is WebSocket Broker Server. This architecture is especially designed for constrained devices.

When a constrained IoT device may just support a fixed set of "things" without any dependencies on other "things", and consider time-series style sensors for example temperature and humidity sensor. 2

There is a use case that have been used in one of my WoT open source projects. This could be summarized in the following architectural pattern.

Figure 1-4: WebSocket Broker Server Figure 1-4: WebSocket Broker Server

  • In this case, constrained devices has a built-in Websocket client, and plays the role of sender client.
  • There must be a Websocket broker (server) which could be deployed as a cloud server instance, or a home IoT gateway.
  • The form of the viewer client could be in Web apps (W3C HTML5), iOS app and etc.

This architecture is trying to give a general purpose framework for very constrained devices to stream series data over WebSocket to user clients. In general, a constrained device doesn't need to contain a built-in WebSocket/HTTP server.

The architecture is also a proposal for hanlding connections from million user clients. When a constrained device has a built-in WebSocket server and used as a data server, it may not be able to accept and serve too many connections because of it has less memory or other limited hardware resources.

Since the WebSocket broker server is possible to hanlde million connections, the hardare specficiton which is running a WebSocket broker server should be PC-style or server farms.

Usage

WebSocket Broker Server is the server implementation at Thing Service Layer of WoT.City WoT Framework. I have described its use case. But I want to summary that in a general speaking way.

  1. For a constrained device sending data streams (time-series data) to the web.
  2. For sensor type constrained device that wants to create single data sink connection.
  3. Sending data streams.

The deploy strategy is as the following.

  1. WoT.City WoT server is installed in a PC-style server, as explained above.
  2. Rather than be a WebSocket streaming client, there is no WoT server installed in a IoT device.

Let's go more technical details in a bit with the following scenario.

Use Scenario

To send the data over the Internet, IoT devices should use the url below to establish a connection with the server.

ws://[hostname]/object/[name]/send  

You must specify an object name and your hostname. For example:

ws://wot.city/object/554785c7173b2e5563000007/send  

To receive data from the server, the frontend should use the url below to establish a connection with the server.

ws://[hostname]/object/[name]/viewer  

Also, you need to specify the object name and hostname. For example:

ws://wot.city/object/554785c7173b2e5563000007/viewer  

In the perspective view of a virtual object, the object has two significant resources, send and viewer. send is to send device data to WebSocket broker server.

Device Implementation

The demo uses Arch Pro IoT Kit which is designed by Seeed Studio and complaint with LPC1768. Please read Arch Pro Wiki for more information. The code use by this chapter can be imported via the following URL.

https://developer.mbed.org/users/jollen/code/Mokoversity_WoT_Wifly_Temperature/  

Please import the project via mbed online compiler.

Implement WoT Server

To implement your own WoT server, server/websocket-broker.js is the getting started example for your reference. Please form the complete source code at WoT.City Github.

The project is structured by the hierarchy as shown in the following figure.

.
├── lib
│   ├── framework.js
│   └── websocketBrokerServer
│       ├── requestHandlers.js
│       ├── router.js
│       └── server.js
└── servers
    └── websocket-broker.js

Files in the folder ./lib are the framework. ./lib/framework.js is the Thing Data Layer which could be considered as the core framework. There are also collections of Thing Service Layer in ./lib. The collections are implementations of various WoT use cases. Each case has its own folder. For example, ./lib/websocketBrokerServer is the use case of WebSocket Broker Server as described above.

Files in the folder ./servers are main server programs. In most case, a server program creates one server instance from Thing Service Layer and then start the server. Additionally, you will implement the service logic at the main server program. For example, the regular expression of URI routing will be at the main program. ./servers/websocket-broker.js shows how to implement the service logic.

Now, it's time to go into the code details. Let's go through ./servers/websocket-broker.js the main server program. The first step is to icnlude the core framework module, as show in the following example.

/**
 * Main WoT Framework
 */
var Framework = require('../lib/framework');  

Then, it's required to include of the of WoT use cases in Thing Service Layer, as this example shows:

/**
 * Main Server Modules
 */
var WebsocketBroker = require("../lib/websocketBrokerServer/server")  
  , WebsocketRouter = require("../lib/websocketBrokerServer/router")
  , RequestHandlers = require("../lib/websocketBrokerServer/requestHandlers");

URL Router represents URI handlers. Its sole job is to parse the URI paths in a WebSocket request. Because of the definition of URI paths may be user-defined or standalized, it's possible to declare as many routers as your needs.

The sugguested way to define a URI path is by regular expression, as this example show:

/**
 * Websocket URL Router
 */
var wsHandlers = {  
   "/object/([A-Za-z0-9-]+)/send": RequestHandlers.send,
   "/object/([A-Za-z0-9-]+)/viewer": RequestHandlers.viewer,
   "/object/([A-Za-z0-9-]+)/status": RequestHandlers.status
};

The implementation of request handlers will be described in the other chapter. One of the most important responsibilities of a software framework is to define the event system. WoT.City WoT framework has this event system. The main server program must implement the event handlers.

The WoT.City WoT framework doesn't define the names of event handlers. However, it's good if you do this at your main server program. To accompulish this, I would suggest that a main server program has a JavaScript class. The following code shows this:

/*
 * Prototype and Class
 */
var Server = function () {

};

/**
 * Event Callback System
 */
Server.prototype.onNewThing = function(thing) {  
  // Call framework APIs
  this.registerThing(thing);
};

onNewThings is the interface name mentioned above. When there is coming a new thing, the server program registers it to the core framework. The framework doesn't register any things by itself, but a main server program is in charge of this.

The framework uses EventEmmiter as the event system. To handle the event newThing from the framework, consider this example:

server.on('newThing', this.onNewThing.bind(this));  

The complete code will be shown in the later section. WoT.City WoT framework will continuously develop a series of common event names, and newThing is the one that had been defined.

Before launching the server which is the last step, the main server program could combine a config object into Server object. Consider this example:

/**
 * Util Modules
 */
var merge = require('utils-merge');

/**
 * Create an WoT server.
 *
 * @return {Object}
 * @api public
 */
function createServer(options) {  
  var instance = new Server();
  return merge(instance, options);
}

We could also put a public method in Server class for launching WebSocket server, as show in the following example:

/**
 * Start a Websocket server.
 *
 * @return {None}
 * @api public
 */
Server.prototype.start = function() {  
  var server = new WebsocketBroker({
    port: this.port,
    host: this.host
  });
  var router = new WebsocketRouter();

  // Events
  server.on('newThing', this.onNewThing.bind(this));

  server.start(router.route, wsHandlers);
};

Final step consists of three actions:

  • Create the Server instance.
  • Create the core framework instance.
  • Copy framework APIs (methods) to server instance.
  • Start the server and listerning for connections.

The following code shows this:

/**
 * Create the server instance.
 */
var wsBrokerImpl = createServer({});

/**
 * Combined server with framework instance.
 */
var wsServer = new Framework({  
    server: wsBrokerImpl
});

/**
 * Start the server.
 */
wsServer.start();  

Copy framework APIs to server instance is much like extending the Server class from Framework class.

REST WoT Server

The next use case of WoT.City WoT framework is REST WoT Server. This architecture, in generally, is only suitable for non-constrained devices. This is also the called Device Server model as described at the beginning of this chapter.

WoT.City WoT framework is gathering use cases by the model of open source development. And a REST WoT server is one of the use cases which has been gathered by WoT.City WoT framework. Also, this means that a REST WoT server is a server implementation of WoT.City WoT framework.

The instance of REST WoT server is a process running on a physical device and serving REST APIs. It is because that the REST WoT server may need to handling large numbers of incoming HTTP requests, it's not suggested to run a REST WoT server instance in a constraned device.

Device Server Implementation

Currently, there does not a REST WoT Server exist in the source tree of WoT.City WoT framework. We use ARM mbed devices in this project, so we implement a REST WoT Server with ARM mbed OS stacks. It's becaseu that running an instance of REST WoT Server with WoT.City WoT framework needs a Node.js runtime, we use ARM mbed OS stacks instead.

HTTP over UDP

The benefit of TCP is that it works more reliable over the networking. However, the primary drawback of TCP is that it is considerably more overhead. There were development works that have been done over the past years.

It is good for using either HTTP or WebSocket. But both of them are TCP connections. We will talk about HTTP over UDP in a bit in the other articles of this series.

Coming

The next coming article of this series will be Modeling Things.

Also See