FreeDOM (Programming)

Examples

Introduction

What is FreeDOM? FreeDOM is a new concept I created that changes a web page into a fully asynchronous event-driven application by using currently available technologies. Below, I will compare FreeDOM with currently working web 2.0 concepts and show you the benefits of switching to this architecture.

Web 2.0 Techniques

There are many ways of creating web pages that go and get content from servers and update themselves. Following is a list of common ways.

  • Ajax: An ActiveX object built into browsers that sends and receives text or XML HTTP requests.
  • IFrame: A built-in browser element control that can send and request web page content similar to Ajax.
  • Comet: A concept of leaving a web page in a state of constant downloading that simulates an HTTP push technology, to receive data events.
  • HTTP Streaming: Using third-party technologies such as Java Applets or Activex to stream data from server to the client.

Most of these concepts come with plenty of downfalls to true application state. Both Ajax and Iframes are very resource intensive. Every time you want to get data from the server, you must create an object or element and send an HTTP Request. This causes the HTTP server to have huge amounts of requests eating up memory and processor time. There is also a delay in response time do to header information being passed back and forth. Also, Ajax and Iframes do not know if there is data available; they have to send a request just to find out if it is available, and once again causes a lot of unneeded talking between server and client. Another issue with HTTP Requests is that they fill up your server logs. This can be a headache for servers with large amounts of traffic. Extremely large logs take up processor time, hard drive space, and backup space. Ajax/Frames also can only receive text or XML. This can be very irritating because, to use it on a page, you must convert it into a usable format. A lot of web sites use an XML objects backend and a JSON objects front end; in doing this, they must have a conversion process. This is at another memory and processor expense.

A lot of developers have noticed these flaws in Ajax and Iframes and have started to invent new technologies. One is Comet, another cleanser name. Comet is very hard to implement and comes with a lot of unknown bugs. Basically, to use it you usually have to create a custom web server because most today were not made to leave requests in an open state. Most servers have timeouts and caching built in to make them faster for a get-in-get-out way of doing business. Comet is a step up from Ajax, but it’s not the cure. Comet can only receive asynchronous events; it cannot talk back to the server. You need to implement Comet to receive and Ajax to send, making Comet dependant on Ajax. Another downside of using Comet is that browsers also have an issue with a never-ending web page. Have you ever been on a page that locks up, causing all your other browsers windows to close? This is caused by the EXE sharing memory and thread space. So, Comet was a great idea but it is not feasible do to with current technology.

Another technology is HTTP Streaming. There is many different versions of HTTP Streaming. One way is to set up a server to talk back and forth to an ActiveX or Java Applet. It’s very hard to implement and maintain, with many security and licensing issues for both client and server. Most users will not install your code because of fears of corrupt code that they will not be able to remove, plus cause damage to their operating system or files. This can be very scary to the end user.

This next section will describe FreeDOM and how it will fix these issues.

FreeDOM!

So, how would one go about fixing these old technologies to make web sites and application one? Should you wait for large companies to create better working browsers or should you invent it now with currently working technologies? As a developer, I feel I should wait… but as an inventor, I have decided to make it work. What I want is the freedom to do what I want and build what I want on a web page. I came up with the name FreeDOM for this reason, plus it is really what you want to do. You want to work with the browser DOM freely and update it whenever you choose. So, I asked myself what current technologies I could use to create a true event state application. One that came to mind was Flash, with so much new hype around AIR and Flex applications. It’s hard not to notice a big boom in Flash usage everywhere since Adobe took over it from Macromedia. Some of the latest usage has said Flash is installed on 90% or more of the machines world-wide across operating systems and browsers. This got me thinking! Could I use Flash in some way with my currently working web page technology? Flash seems to work well for creating banners and animation, but could it handle passing data back and forth? After some testing with ActionScript 3.0, I have figured out a way to replace Ajax, Iframes, Comet, and HTTP Streaming.

How Does FreeDOM Work?

FreeDOM works by using Flash Binary Sockets to communicate with your Custom Socket Server. To pass binary data from Flash sockets to your JavaScript web page, you need a custom class called ExternalInterface. This class will allow you to make calls to Flash methods and add callbacks for your JavaScript methods. So, take a look at some code so you will understand.

Flash SWF Code

Add the following code to a document class .AS file. It is a wrapper for the custom JSocket class and main movie clip. Please keep in mind to keep the size of this and your JSockets small. By keeping them small, you can load everything in the first preloader frame and bypass the activate SWF message.

package {
   //Imports--------------------
   //To communicate with JavaScript
   import flash.external.ExternalInterface;
   import JSockets.JSocket;            //JSocket
   import flash.display.MovieClip;     //Movie Clip
   import flash.system.Security;       //For Domain Security

   import flash.text.TextField;
   import flash.text.TextFieldAutoSize;
   import flash.text.TextFormat;
   //---------------------------
   //Main Class for creating javascript sockets
   public class Main extends MovieClip {
      //Create Properties----------------
      private var SocketArray:Array;
      //---------------------------------

      //Constructor
      public function Main() {

         //Add Javascript EntryPoints-------------------
         ExternalInterface.addCallback("CreateSocket",
                                       this.CreateSocket);
         ExternalInterface.addCallback("Connect", this.Connect);
         ExternalInterface.addCallback("Close", this.Close);
         ExternalInterface.addCallback("Flush", this.Flush);
         ExternalInterface.addCallback("Send", this.Send);
         //---------------------------------------------
      }
      //Creates a socket for use in javascript
      public function CreateSocket(_ID:String, _Cls:String,
                                   _Con:String, _Ioe:String,
                                   _Se:String, _Dat:String):void {
         var NS:JSocket = new JSocket();
         NS.ID                         = _ID;
         NS.CloseEventCallback         = _Cls;
         NS.ConnectEventCallback       = _Con;
         NS.IOErrorEventCallback       = _Ioe;
         NS.SecurityErrorEventCallback = _Se;
         NS.SocketDataEventCallback    = _Dat;
         this.SocketArray              = new Array();
         this.SocketArray.push(NS);
      }
      //Gets the socket object
      private function GetSocket(_ID:String):JSocket {
         for each (var S:JSocket in this.SocketArray) {
            if (S.ID == _ID) {
               return S;
            }
         }
         return null;
      }
      //Connects to a host and port
      public function Connect(_ID:String, _Host:String,
                              _Port:uint):void {
         //Get Working Socket----
         var FS:JSocket = this.GetSocket(_ID);
         //----------------------

         if (FS) {
            FS.Connect(_Host, _Port);
         }
      }
      //Closes a connection to a host
      public function Close(_ID:String):void {
         //Get Working Socket----
         var FS:JSocket = this.GetSocket(_ID);
         //----------------------
         if (FS) {
            FS.close();
         }
      }
      //Flushes a connection
      public function Flush(_ID:String):void {
         //Get Working Socket----
         var FS:JSocket = this.GetSocket(_ID);
         //----------------------
         if (FS) {
            FS.flush();
         }
      }
      //Sends data to a connection
      public function Send(_ID:String, _Data:String):void {
         //Get Working Socket----
         var FS:JSocket = this.GetSocket(_ID);
         //----------------------

         if (FS) {
            FS.writeUTFBytes(_Data);
         }
      }
   }
}

Next is the JSocket Class that wraps the Flash sockets class. Below is the code for that.

package JSockets{
   //Imports--------------------
   //To communicate with JavaScript
   import flash.external.ExternalInterface;
   import flash.net.Socket;    //Flash Socket Class
   import flash.errors.*;      //Flash Errors
   import flash.events.*;      //Flash Events
   //---------------------------
   //Actual socket class
   public class JSocket extends Socket {
      //Create Properties---------------
      public var ID:String;
      public var Host:String;
      public var Port:uint;
      public var CloseEventCallback:String;
      public var ConnectEventCallback:String;
      public var IOErrorEventCallback:String;
      public var SecurityErrorEventCallback:String;
      public var SocketDataEventCallback:String;
      //--------------------------------
      //Constructor
      public function JSocket() {
         AttachEvents();
      }
      //Attach Events
      private function AttachEvents():void {
         //Add Event Handlers-------------------------------------
         addEventListener(Event.CLOSE, Handler_Close);
         addEventListener(Event.CONNECT, Handler_Connect);
         addEventListener(IOErrorEvent.IO_ERROR, Handler_IOError);
         addEventListener(SecurityErrorEvent.SECURITY_ERROR,
                          Handler_SecurityError);
         addEventListener(ProgressEvent.SOCKET_DATA,
                          Handler_SocketData);
         //-------------------------------------------------------
      }
      //Connects to a host and port
      public function Connect(_Host:String, _Port:uint):void {
         Host = _Host;
         Port = _Port;
         //Call socket connect---
         connect(Host,Port);
         //----------------------
      }
      // Handles the close event
      private function Handler_Close(event:Event):void {
         ExternalInterface.call(this.CloseEventCallback,
                                event.type);
      }
      // Handles the connect event
      private function Handler_Connect(event:Event):void {
         ExternalInterface.call(this.ConnectEventCallback,
                                event.type);
      }
      // Handles if io error event
      private function Handler_IOError(event:IOErrorEvent):void {
         ExternalInterface.call(this.IOErrorEventCallback,
                                event.type, event.text);
      }
      // Handles security error event
      private function Handler_SecurityError
         (event:SecurityErrorEvent):void {
         ExternalInterface.call(this.SecurityErrorEventCallback,
                                event.type, event.text);

      }
      // Handles socket data event
      private function Handler_SocketData(event:ProgressEvent):void {
         ExternalInterface.call(this.SocketDataEventCallback,
            event.type, this.readUTFBytes(this.bytesAvailable));
      }
   }
}

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read