Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Using XMLSocket for Server Push in Flex
How to program a server push in ActionScript and Java

Adobe's LifeCycle Data Services ES offers developers powerful capabilities. Some of this software’s capabilities, specifically server push, can be developed with relative ease using a utility class that has been around in the Flash APIs for a great while, and without having to pay licensing fees for LifeCycle Data Services ES. The utility class spotlighted in this article is flash.net.XMLSocket, and it provides all the client-side plumbing required for implementing server push.  In the context of this article, server push is defined as the ability for a client to register with a server its interest in remote data events such that when an event occurs, a notification (and perhaps related data) is pushed from the server out to the client without the client implementing a polling mechanism.

The naming of the XMLSocket class is easily misconstrued because there is no physical enforcement within the class implementation that ensures data are in an XML format.  However, in the scope of this article, server push is implemented by sending XML over the wire. Firstly, the Flex APIs offer a rich set of XML parsing capabilities with E4X. Second, tools and techniques to manage XML document creation are very mature at this point, thus allowing the developer to design, document and communicate the wire level format in a straightforward manner. Lastly, debugging is much easier with a tunnel when the stream under monitor is textual, i.e. XML, and not binary.

Defining the XML Protocol
Defining the protocol that the client and server will follow is the logical place to start the design. This can be a time consuming effort; the best heuristic is to keep it simple.  In most cases, defining a simplified protocol that relies on key-value pairs offers maximum flexibility.  Defining a more advanced protocol with namespaces and all-things-XML certainly may increase the capabilities, but not without a price. Consider the level of effort required to develop custom parsers, the actual performance impact at runtime for parsing deeply nested XML documents that require validation, etc.  

The following simplistic protocol is going to be used to demonstrate server push in this article.

<register event=”<event name>”/>

<response success=”<true | false>” error=”<error text>”/>

<event name=”<event name>”>
    <property name=”<property name” value=”property value”/>
    …
</event>

<quit/>

<shutdown/>

The client informs the server of its event interests through the register element. The server will acknowledge that event registration with a response element. If the event is well known, the response will indicate success, otherwise it will indicate failure with an appropriate error string. When the server detects an event of that type, it will push the related data out to the client using the event element. Finally, the client has the power to either quit, leaving the server running for other clients, or shutdown the server in its entirety. Once the protocol has been fully defined, focus turns towards client and server implementations. Which one is implemented first is a matter of personal preference.

The high level steps to implementing the client-side aspects of server push are as follows:

1.    Instantiate a new XMLSocket instance
2.    Register event listeners to respond when data events are received
3.    Establish a connection with the server.
4.    Register one or more events with the server
5.    Implement the listener function to act when data events are received

Implementing the server-side logic requires substantially more work then that required to implement the client. There are many more complex issues at stake. At a minimum, the server needs to be multi-threaded. How will the server be managed, perhaps JMX?  What are the logging facilities going to look like? What about authentication and authorization issues? These issues, and more, are likely to crop up during the design of the server. For the purpose of this educational article, complex issues like multi-threaded design, authentication, etc. will be sidestepped. (I do, however, cover some of these issues in greater detail over at my blog ) Only a brief review of the Java code associated with this article will be done since this is, after all, a Flex oriented article. Also, Java is but one implementation option for the server—it could be written in Ruby, Python, .NET, etc.

All of the code can be downloaded from http://www.beadlefox.com/xmlsocket.zip

Server Architecture Review
The Java server is implemented in the SimpleServer class. This class relies on the ServerSocket class to listen for and accept client requests. When the server is instantiated, it spawns a separate thread that generates random events using an instance of RandomEventGenerator. For purposes of this demo, the “events” are simply named A, B, and C and the generator uses Math.random() as its generation algorithm. The generator maintains what equates a list of listeners for each event. When the event is generated, the listeners list is iterated and each listener is notified. Notification is encapsulated behind the RandomEventListener interface that defines an onEvent() method. In a more realistic example, the listener would subscribe to JMS queues or topics, and the onEvent() method would be replaced with the JMS onMessage() method.  However, for this short article incorporating a JMS server like ActiveMQ would be overkill and arguably clutter the example code more then is required, especially since non-Java servers are not going to use the JMS APIs.

When a client establishes a connection with the server, a new dedicated thread implemented by the ClientThread class is spawned. This thread will remain active until the client either quits or some client issues a shutdown command that terminates the server. The thread responds to the XML sent to it from the client appropriately. In particular, if the thread detects a register event it contacts the RandomEventGenerator and registers itself as a listener for the event named by the client.  At this point, the thread acknowledges the event registration back to the client per the protocol design, and then waits.  When an onEvent() is received by the thread, it sends the event notification over to the client via server push.  This is the true power of this architecture since the client doesn’t have to implement a loop or perform any type of polling operation. The only thing the client has to do is register an event listener.

When sending data from the server back to the client, it is imperative that the response be properly delineated. The Flash Player seems to require a very specific termination sequence of a carriage return followed by a null byte (“\r\0”) before the XMLSocket dispatches the DataEvent for processing. If this sequence isn’t included, the client side event is never fired!

To launch the server, invoke the following command with an appropriate “/” or “\” if the OS is Windows or *nix inside of the ./src/SimpleServer directory:

/src/SimpleServer $java -cp ./bin com.beadlefox.xmlsocket.SimpleServer

Client Architecture Review
The Flex client is implemented in the XmlSocketClient class. The UI is meant to be educational, so it is oversimplified with 5 buttons used to connect, register and shutdown the remote server. The server must be up and running at this point in order for the Flex UI to connect successfully. This application implements the 5 steps outlined earlier. The first 3 steps are implemented in the application’s connectToServer() function.  

//
            
// The XMLSocket instance
            
//
private var socket:XMLSocket;


private function connectToServer():void
{
    //
    // Step #1: Create the XMLSocket Instance
    //
    socket = new flash.net.XMLSocket();
    
    //
    // Step #2: Register for event notifications
    //
    socket.addEventListener(Event.CONNECT, connectHandler);
    socket.addEventListener(DataEvent.DATA, dataHandler);
    
    //
    // Step #3: Create the physical connection with the server
    //
    socket.connect("localhost", 5974);
}

The 4th step occurs when the register() function sends the XML request that indicates what event(s) the client wants to be notified of via server push. Notice the string includes a \n which is required by the server since readLine() is used in the Java code. Once the XML string has been assembled, passing it to the XMLSocket send() method automatically transmits the message over the wire.

//
// Step #4:
// Registers with the server that this client
// is interested in the named event
//
private function register(eventName:String):void
{
    var request:String = "<register event=\"" + eventName + "\"/>\n";            
    socket.send(request);    
}

Finally, when the server sends data over to the client, the listener function implemented as the 5th and final step processes and responds appropriately. In this case, it merely pushes the data object into the data provider for display on the screen.

//
// Step #5:
// Process the data sent to the client from the server
//
public function dataHandler(event:DataEvent):void
{
    //
    // Data has been received from the server
    //
    var xml:XML = new XML(event.data);
    
    //
    // What is the name of the root element?
    //
    var element:String = xml.name().toString();
    
    if(element == "response")
    {
        //
        // Swallow this event - for demo just
        // assume success
        //
    } else if(element == "event")
    {
        //
        // Push the event to our data provider
        //
        var obj:Object = new Object();
        obj.id = nextId++;
        obj.eventName = xml.@name;
        obj.timestamp = xml.property.@value;
        events.addItem(obj);
    }
}

The DataEvent’s data property contains the XML sent over from the server. Using E4X, the listener inspects the root element to determine how it should respond to the data it just received.  In a more powerful architecture, an Abstract Factory could be used to dynamically instantiate a concrete class based on the root element. This concrete class would then know how to fully parse and respond to the event, creating the opportunity to respond to a limitless number of XML document structures.

The rest of the MXML and ActionScript in the sample is straightforward—buttons with click methods, a data grid to display the received data, etc.

Conclusion
This sample demonstrates that with very little work on the Flex side it is possible to harness the power of server push without incurring the licensing costs of LifeCycle Data Services ES.  The benefit of server push is that no client polling is required; this also reduces the load of the server because it doesn’t have to constantly respond to clients checking for new data.  Beyond the protocol design, which is implementation language agnostic, the most complicated effort lies in designing the multithreaded server. The decision to implement a server or license Adobe’s solution is likely ultimately decided based upon the situation.  If only server push is required, a home grown solution with XMLSocket may be the most cost effective approach, and the implementation may only require a couple of man hours of effort.

After Thoughts: Server Push and Tomcat
The Tomcat server is widely deployed in production environments today.  Its architecture is completely pluggable, including its Connectors that know how to process and dispatch wire-level traffic.  I’m looking to find some interested people that want to help me launch a new open source project with an Apache style license to implement a new Tomcat Connector capable of providing initially server push capabilities to a Flex/Flash client. For those looking for more information on what I’m calling the XSock Protocol, including why I think there is a need for this Tomcat ProtocolAdapter, please visit http://www.xsock.org. This is truly the beginning of the project, so it’s a great opportunity to get in early and be a major contributor!

About Jason Weiss
Jason Weiss has over 12 years of real-world design and development experience. He's a published author and frequently lectures at industry trade shows.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Hi,

We have found that the "\r" isn't necessary to get the DataEvent to fire. All you need is the "\0".

What did cause us some confusion is that we were using the PrintWriter in java and didn't read the documentation properly. We found the println() method flushes the output buffer (and sends the data through the socket), but print() does not. You need to call the flush() method manually.

A snippet from our working code:

out = new PrintWriter(socket.getOutputStream(), true);

in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

out.print("string 1\0");

out.flush();

Also worth checking:
- Make sure your port is greater than 1023
- Make sure the socket server is on the same domain as the swf

-Stuart

Hi,

The XML termination sequence you refer to ("/r/0") is causing a great deal of frustration on this end because everything else is setup between the client and the server (the Flash player recognizes server connect and close events) but the DataEvent is not being dispatched by the XMLSocket when the Server sends XML data to the client.

We are trying different termination sequences to see if one of them will work. We are also looking at the Java outputstream wrappers to see if this is potentially an issue.

Any further comments, suggestions, or feedback would be greatly appreciated.

-Chris
crm6360@hotmail.com


Your Feedback
Stuart McIntyre wrote: Hi, We have found that the "\r" isn't necessary to get the DataEvent to fire. All you need is the "\0". What did cause us some confusion is that we were using the PrintWriter in java and didn't read the documentation properly. We found the println() method flushes the output buffer (and sends the data through the socket), but print() does not. You need to call the flush() method manually. A snippet from our working code: out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.print("string 1\0"); out.flush(); Also worth checking: - Make sure your port is greater than 1023 - Make sure the socket server is on the same domain as the swf -Stuart
Chris Mamorella wrote: Hi, The XML termination sequence you refer to ("/r/0") is causing a great deal of frustration on this end because everything else is setup between the client and the server (the Flash player recognizes server connect and close events) but the DataEvent is not being dispatched by the XMLSocket when the Server sends XML data to the client. We are trying different termination sequences to see if one of them will work. We are also looking at the Java outputstream wrappers to see if this is potentially an issue. Any further comments, suggestions, or feedback would be greatly appreciated. -Chris crm6360@hotmail.com
Latest Cloud Developer Stories
Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON Featured Whitepapers
ADS BY GOOGLE

Breaking Cloud Computing News

The Khronos™ Group, an industry consortium creating open standards for the accelera...