How We Developed A LiveCam App on Windows Azure

Web cams allow users to view video streaming in a real time or get specific frames upon request. However, the cams can’t store video for a long time due to the resources required for storing video or photo collections. With this in mind, we decided to build the Enterra WebCam Viewer.

Enterra WebCam Viewer – is a web application with the following features:

  • When user opens the application they are presented with a list of public cameras served by the application (ie cameras for which video is archived).
  • When the user goes to a certain camera, they should have an option to view video (or separate frames) for a specified time period.

These features are features for a user with “Guest” permissions. Cameras can’t appear in the application by themselves and someone has to add them. So we needed to implement features to register and add camera’s, namely:

  • New user registration plus simple user account management (password change)
  • User cameras management: camera creation, camera deletion, camera edit.

A video archive for a camera is formed from the frames taken from the camera within a certain interval. For example, an ordinary video is a sequence of frames with frequency of 24-25 frames per second. Full motion video record with such frequency requires a substantial consumption of processor time and disk space. In this application the user should have the option of specifying the frame frequency, which should not be set any lower than 1 frame per second. In addition the user should have an option to stop camera record without its deletion.

System Requirements

From the features description one can conclude that we need substantial processing resources. First of all, the cameras should constantly be served, frames should be taken from them and frames should be stored. Secondly, clients will constantly request videos and the server should make frame selections and send them to clients. In addition the server platform should be scalable and that  is why the Windows Azure platform was a natural choice. We also used C#, Silverlight 3.0 and SQL Azure.

Application Architecture

Enterra WebCam Viewer is a client-server application, which has the following layers:

  • Data Provider Layer – Database is a data source on the server and server interface is a data source on client. Therefore we use IDataProvider – to unify the interface of data access both on the client and on the server.
  • Business Objects Layer – Business objects is the most convenient way of getting and changing data, which is abstracted from the method of data storage and data transfer. Servers and clients both have business objects.
  • Business Logic Layer – Business logic is processing of events or data gathering.

The architecture described above is implemented with the help of our Enterra.Data component, which is used both on the client and server. That is why we had to port Enterra.Data to Silverlight which didn’t present any problems.

From the Enterra WebCam Viewer functionality described above, the following object application model is appropriate:

  • User – business object for storing user properties (login, password, e-mail etc)
  • Image Source – business object corresponding to the image entity. Image source is a web camera abstraction. Properties of the image source are web camera address, web camera state (stop, record), link to user-owner, access level to web camera (available to all users or only to the owner).
  • Image Data – business object for storing images taken from the web camera. Properties of the Image Data are the binary data of the image itself, creation date, and the link to the image source.

The database scheme corresponds to object model and is shown below:

Interaction With Server

As noted in the architecture description, client interacts with server by using the IDataProvider interface. This means that our server is an implementation of IDataProvider. The code samples below show examples of the most significant IDataProvider methods:
object GetNewId(Type type)
//getting identificator for a new object of the specified type.
NameValueDictionary LoadData(Type type, object id)
// load of object properties with specified identificator and type.
NameValueDictionary[] LoadData(Type type, Filter filter, Order order)
//load of properties massive for objects of the specified type. Objects selection on server is done using a specified filter with specified sorting means.
void Save(ChangedData[] changes)
// saving changes in objects

It is clear that the IDataProvider implementation on client should transfer requests by web service methods. Instead of creating of several methods on the web service, our web service publishes a single method. Calls for all the methods by the server is done using this method. It’s signature is below:

object InvokeAny(string methodName, object[] args)

There are a number of advantages in the creation of a web service method, namely:

  • A central location for request processing on the client and server. For example, this is convenient for exclusions processing and logging.
  • Problems with the transfer of arguments of different types are focused in only one method (not spread across the whole service).
  • Having set only one method, we abstract away from web service technology. If we decide, for example, to use WCF, it will be easier for us to move to WCF by refactoring only one method.

We came across one more big problem, the Enterra.Data component and our experience in development of client-server applications using the component impose a synchronous request model on server methods. That is when requests are made to any IDataProvider method we always get a result (or exclusion). Synchronous requests are impossible in Silverlight. That is why a problem exists in using client-server components with synchronous the request paradigm and needs to be solved. It is inadvisable to redevelop a component with a synchronous paradigm into a component with asynchronous requests.
We solved this problem the following way:

  • For Enterra.Data we implemented IDataProvider by asynchronous requests to server. Synchronization of IDataProvider requests is achieved by inserting code with a reply standby loop.
  • As getting results from server on Silverlight is done in the main stream, we can’t make a request to the server in the UI events handler. To solve this we created a SyncInvoker class which receives two delegates: the 1st delegate has code with requests to server, the 2nd delegate is requested when the 1st one is finished. SyncInvoker launches the 1st delegate in a separate stream and finishes then the 2nd delegate launches.

We concluded that we should use components with a synchronous request model in an asynchronous environment.

Pages: 1 2


Array
Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!