Friday, September 14, 2012

BlazeDS, LCDS and Flex-Java Interaction (Part 2)

Question: What do we mean by serialization/deserialization and Marshalling/UnMarshalling?
Answer: We can use remoting in blazeDS/LCDS to make use of server-side logic and  get the result back in Flex Client. Whenever we call any function on server side we generally pass some value-objects/primitives to server and there this marshalling (or serialization) comes into picture.

The conversion between data types in actionscipt to corresponding data types to Java (or any other supported server side laguage) is main idea of marshalling or serialization. While we receive data back from server side it is referred to as deserialization or un-marshalling. We can also use instances of our own custom (value objects) and then provide complete path of the corresponding value-object (in remote object tag)on server side to help blazeDS and FVM (Flash Virtual Machine) to cooperate in serialization/de-serialization.
BlazeDS uses the AMF binary protocol to serialize and deserialize Java classes, and the Flash Player does the same for the Flex classes on the client side.The use of a AMF binary data transfer format increases performance, allowing applications to load data up to 10 times faster than with text-based formats such as XML or SOAP.

Question: What is AMF protocol and where is it used?
Answer: AMF stands for Action Message Format. It is binary data prorocol supported by Flash Virtual Machine. It can be best described as SOAP-RPC hybrid, in which data is transferred via Remote Procedure Calls. This protocol is open source now.
Advantages of AMF include: rapid data transfer, automatic marshalling and unmarshalling of data objects by the FVM, support across the entire spectrum of server side languages including .NET, PHP, Java, Ruby, and Python.
Disadvantages of AMF include: proprietary protocol that is not compatible with other client-side RIA development platforms such as DOJO, Scriptaculous, and SilverLight.  However, JavaScript communication via AMF with a server language is made possible through the Adobe AIR platform.


Question: Can we achieve custom serialization/de-serialization?
Answer: Yes. The solution is to use flash.utils.IExternalizable interface in ActionScript which is compatible with java.io.IExternalizable API. We need to implement these interfaces on the client side and server side value objects respectively to take control of their serialization The API requires two methods readExternal() writeExternal() which take flash.utils.IDataInput and flash.utils.IDataOutput streams respectively. The implementations of these methods mirror the server Java class, which implements java.io.Externalizable – also with two methods readExternal() and writeExternal() taking java.io.ObjectInput and java.io.ObjectOutput streams respectively.


 public void writeExternal(ObjectOutput out) throws IOException 

 {    

    out.writeObject(id);    

    out.writeObject(name);   

    out.writeObject(description);   

    out.writeInt(price);  

 }  

 …mirrors the client readExternal method in ActionScript:  

 public function readExternal(input:IDataInput):void{  

    _id = input.readObject() as String;    

   name = input.readObject() as String;    

   description = input.readObject() as String;    

   price = input.readInt();  

 }  
A similar relationship exists for the reverse situation for sending instances back from the client to the server.


Question: Now we know that we can write custom serialization/de-serialization routines, but sometimes these are invoked for Flex->Server (BlazeDS) direction and not for Server->Flex Direction. What can be done to solve this problem?
Answer:If we encounter any such problem then the solution is to write own AMFEndpoint class and relevant serialization class.

Channel-Definition


<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
        <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="ch.hedgesphere.core.blazeds.endpoint.AMFEndpoint"/>

         <properties>
            <serialization>
                <type-marshaller>ch.hedgesphere.core.blazeds.translator.HedgesphereASTranslatortype-marshaller>
            serialization>
        properties>

    channel-definition>

Custom AMF Endpoint
 
package ch.hedgesphere.core.blazeds.endpoint;


import ch.hedgesphere.core.blazeds.serialization.Serializer;

    public class AMFEndpoint extends flex.messaging.endpoints.AMFEndpoint {

    @Override
    protected String getSerializerClassName() {
        return Serializer.class.getName();
        }

    }

Custom Serializer

 package ch.hedgesphere.core.blazeds.serialization;

import java.io.OutputStream;
import flex.messaging.io.MessageIOConstants;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfMessageSerializer;
import flex.messaging.io.amf.AmfTrace;
public class Serializer extends AmfMessageSerializer {

    @Override
    public void initialize(SerializationContext context, OutputStream out, AmfTrace trace)
    {
        amfOut = new AMF0Output(context);
        amfOut.setOutputStream(out);
        amfOut.setAvmPlus(version >= MessageIOConstants.AMF3);

        debugTrace = trace;
        isDebug = trace != null;
        amfOut.setDebugTrace(debugTrace);
    }
}
Custom AMF0 Handling

 package ch.hedgesphere.core.blazeds.serialization;

import flex.messaging.io.SerializationContext;
public class AMF0Output extends flex.messaging.io.amf.Amf0Output {
public AMF0Output(SerializationContext context) {
    super(context);
}
@Override
    protected void createAMF3Output()
    {
        avmPlusOutput = new AMF3Output(context);
        avmPlusOutput.setOutputStream(out);
        avmPlusOutput.setDebugTrace(trace);
    }
}

Custom AMF3 Handling


package ch.hedgesphere.core.blazeds.serialization;
import java.io.IOException;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
import flex.messaging.io.SerializationContext;
public class AMF3Output extends flex.messaging.io.amf.Amf3Output {
public AMF3Output(SerializationContext context) {
    super(context);
}
@Override
public void writeObject(Object value) throws IOException {
    if(value instanceof DateTime) {
        value = convertToDate((DateTime)value);
    }
    if(value instanceof LocalDate) {
        value = convertToDate((LocalDate)value);
    }
    if(value instanceof LocalTime) {
    value = convertToDate((LocalTime)value);
    }
    super.writeObject(value);
}
private Object convertToDate(LocalTime time) {
    return time.toDateTimeToday().toDate();
}
private Object convertToDate(LocalDate date) {
    return date.toDateMidnight().toDate();
}
private Object convertToDate(DateTime dateTime) {
    return dateTime.toDate();
}   }

Custom Marshaller from Flex->Java

@SuppressWarnings({"rawtypes"})

@Override
public Object convert(Object originalValue, Class type) {
    if( type.equals(DateTime.class)) {
        return convertToDateTime(originalValue);
    }
    if( type.equals(LocalDate.class)) {
    return convertToLocalDate(originalValue); 
    }
    if( type.equals(LocalTime.class)) {
        return convertToLocalTime(originalValue);
    }

    return super.convert(originalValue, type);
}
private Object convertToLocalTime(Object originalValue) {
    return originalValue == null ? null : new LocalTime(originalValue);
}
private Object convertToLocalDate(Object originalValue) {
    return originalValue == null ? null : new LocalDate(originalValue); }
private Object convertToDateTime(Object originalValue) {
    return originalValue == null ? null : new DateTime(originalValue);
}
@SuppressWarnings({"rawtypes"})
@Override
public Object createInstance(Object source, Class type) {
    return super.createInstance(source, type);
}
}


Question:The main problem in serialization/de-serialization occurs when we are using numeric types. Actually Flex does not have null data type and when a null value comes from java side it is converted to zero. Also no datatype in Flex can hold a value of long data type in Java. In case precision matters we need to write our own custom solution. What can be done?
Answer: BlazeDS uses a BeanProxy to read and write attributes into an object (using its getters and setters), and to convert it to the right type if needed. That is an ideal place to customize. When reading values i.e. sending them to Flex (from Java) it is fine but when values move from flex to java it is problem because it will handle setting the properties of object but not handle the conversion when the number is an argument to remote call. For that to work a custom NumberDecoder is needed. As there is no mechanism to write custom decoder, we also need to replace TypeMarshaller.

Above excerpt is taken from the following link:
http://labs.bsb.com/2010/11/serialization-of-numeric-types-with-blazeds/

Custom Component in Flex (Part Three)

In second part, we talked about the methods that need to be overridden while creating custom components. There is no silver bullet to kill all the confusions, writing custom component comes by going through some good examples and by practicing them. Let us consider one example where I want to create a simple breadcrumb navigator. One example is below:

So lets do some brain storming. First assumption is the number of breadcrumb items will be known in advance. All the items must reside in some sort of container, so one suggestion would be to extend SkinnableContainer or may be Border Container. Which one shall we choose depends on our requirements? What capabilities do we need for our container etc. Moreover BorderContainer extends SkinnableContainer and has some additional benefit of quickly setting up border.



Second, we can use buttons to represent our breadcrumb items. We can write custom skins for the buttons. First button and last button may have different skins, rest will have same sort of skin. We can also add event listener to all the buttons in partAdded() method, and they will also be removed in partRemoved() method. The click action can be handled in respective click handler method defined for the click event on every button. We can dispatch an event also from here. We can define that event as metadata tag on the top of the component. One detailed example can be found here.

We need to understand one thing very clearly. If we want any component to be skin part (in simple terms, somehow available in the visual appearance of the component), then the best place to add all the event handlers to that component is partAdded() method. We seldom need to override updateDisplayList() method etc for Spark components. But that happens when component need to know some particular positioning information etc. of a skin part, e.g. in Slider component. Otherwise all the components follow up some standard conventions. Based on user action we want visual appearance of the component to change, for that we can use getCurrentSkinState() method that will provide the current state of the skin (and not the component, component state and skin state are two different things).

It is difficult to cover all the aspects here, so I am giving some useful links below:
http://saturnboy.com/2010/06/drawer-component-flex-4/
http://flexponential.com/2010/01/24/custom-focusskin-for-spark-components-in-flex-4/
http://weblog.mrinalwadhwa.com/2009/12/01/custom-components-in-flex-4/

Saturday, September 1, 2012

Custom Component in Flex (Part Two)

We have already got the introduction of basic custom components in part one. Here I will move to advanced custom component creation. Most of the times advanced custom components are created in ActionScript. First thing we need to decide is whether we want a skinnable component or the one without skin. In a skinnable component it has two parts: main component class and skin class. All the aspects of  visual appearance will be defined in skin and the logical (and behavioral) aspects will be covered by main component. For that we need to have a basic understanding of how the component and corresponding skin interacts. So we generally extend one of the component extending SkinnableComponent or the one extending from UIComponent. We may also write a component extending directly from these classes, but it is very less likely due to complexity involved.

The following protected methods (one or more) need to be overridden for Spark components (as mentioned in documentation):
SkinnableComponent method
Description
attachSkin()
detachSkin()
Called automatically by the commitProperties() method when a skin is added, attachSkin(), or a skin is removed, detachSkin()
partAdded()
partRemoved()
Called automatically when a skin part is added or removed. You typically override partAdded() to attach event handlers to the skin part, configure the skin part, or perform other actions when a skin part is added. Implement the partRemoved() method to remove the even handlers added in partAdded().
getCurrentSkinState()
Called automatically by the commitProperties() method to set the view state of the skin class.

The following needs to be overridden for Halo components (ones extending from UIComponent, mostly flex 3 components):
UIComponent method
Description
commitProperties()
Commits any changes to component properties, either to make the changes occur at the same time or to ensure that properties are set in a specific order.
createChildren()
Creates any child components of the component. For example, the Halo ComboBox control contains a Halo TextInput control and a Halo Button control as child components.
Typically, you do not implement this method in a Spark component because any child components are defined in the skin class.
This topic does not describe how to implement the createChildren() method. For more information, see the example for creating a Halo component in Implementing the createChildren() method for MX components.
measure()
Sets the default size and default minimum size of the component.
You typically do not have to implement this method for Spark components. The default size of a Spark component is defined by the skin class, and by the children of the skin class. You also set the minimum and maximum sizes of the component in the root tag of the skin class.
This topic does not describe how to implement the measure() method. For more information, see the example for creating a MX components inImplementing the measure() method for MX components.
updateDisplayList()
Sizes and positions the children of the component on the screen based on all previous property and style settings, and draws any skins or graphic elements used by the component. The parent container for the component determines the size of the component itself.
Typically, you do not have to implement this method for Spark components. A few Spark components, such as spark.components.supportClasses.SkinnableComponent, do implement it. The SkinnableComponent class implements it to pass sizing information to the component's skin class.
This topic does not describe how to implement the updateDisplayList() method. For more information, see the example for creating a Halo component in Implementing the updateDisplayList() method for MX components.

One important thing to observe is: separation of behavior and visual appearance in case of Spark components. That why they are preferred by me and I will cover some examples for that in next post.

Thursday, July 26, 2012

Custom Component in Flex (Part One)

Finally here is the long waited post. This post will have many parts as this topic can not be covered in one post. So first question is What is Custom Component? In very simple terms a custom component is a component which is customized (changed in someway) to suit our requirements. It may be a brand new components or may be an extension of existing component.
Now there can be various scenarios when we need custom components. We need custom components for many reasons, some of them are:
1. The existing standard component does not provide the functionality we need. Some examples can be: we want a prompt text in a textinput that will help user in inserting proper text inside it (promptText property is now available for Spark TextInput but it was not there previously). Another example can be where we want some very small visual change for the component (Round corner button with label Submit say). This can lead to change in skin if we use spark component or overriding updateDisplayList for UIComponent.
2. Another reason may be we need a component and no existing component can serve the purpose. In one of my project I need a highly flexible Locomotive component. I had to start from the scratch using graphics and all.
3. Another reason may be we have some particular set of lines in our MXML code and that is needed everywhere. For example we have a combo box that is containing the list of countries/states and we want that combo box at multiple places in our application. One option is to copy the code everywhere. The problem will appear when we need to make frequent changes to that combobox (may be adding new countries/states based on some conditions). A better option is to create a MXML or ActionScript component based on combobox and provide all the values inside it and then use it everywhere. Creating it in MXML will be easy but it would be more efficient in ActionScript. Actually when we need lot of customization and also have concern for code performance then we prefer ActionScript. For very minor changes going with MXML is also fine, as doing the same in ActionScript may be over engineering some times. Check the following example taken from Adobe website:


 <?xml version="1.0"?> 

 <!-- createcomps_intro\StateComboBox.mxml --> 

 <!-- Specify the root tag and namespace. --> 

 <s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009"  



   xmlns:s="library://ns.adobe.com/flex/spark"  

   xmlns:mx="library://ns.adobe.com/flex/mx"> 

   <s:dataProvider>   

     <s:ArrayList> 

       <fx:String>AP</fx:String> 

       <fx:String>UP</fx:String> 

       <fx:String>MP</fx:String> 

       <!-- Add all other states. --> 

     </s:ArrayList> 

   </s:dataProvider> 

 </s:ComboBox>  


Now we can use it anywhere like:


 <?xml version="1.0"?> 

 <!-- createcomps_intro/IntroMyApplication.mxml --> 

 <!-- Include the namespace definition for your custom components. --> 

 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"  

   xmlns:s="library://ns.adobe.com/flex/spark"  

   xmlns:mx="library://ns.adobe.com/flex/mx" 

   xmlns:MyComp="*"> 

   <!-- Use the filename as the MXML tag name. --> 

   <MyComp:StateComboBox/> 

 </s:Application>  



So these are some of the reasons. I have already given one very simple example of custom component above. We can also create very simple custom component in ActionScript as well. Lets create a button with label 'Submit'. This can also be done in MXML but it can also be done in ActionScript easily. How to write a custom component and how to decide between MXML and ActionScript comes with practice.


 package myComponents 

 { 

   // createcomps_intro/myComponents/MyButton.as 

   import spark.components.Button; 

   public class MyButton extends Button { 

     // Define the constructor.  

     public function MyButton() { 

       // Call the constructor in the superclass.  

       super(); 

       // Set the label property to "Submit". 

       label="Submit"; 

     } 

   } 

 }  


This can be used as:


 <?xml version="1.0"?> 

 <!-- createcomps_intro/MyApplicationASComponent.mxml --> 

 <!-- Include the namespace definition for your custom components. --> 

 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"  

   xmlns:s="library://ns.adobe.com/flex/spark"  

   xmlns:mx="library://ns.adobe.com/flex/mx"  

   xmlns:MyComp="myComponents.*"> 

   <!-- Use the filename as the MXML tag name. --> 

   <MyComp:MyButton/> 

 </s:Application>  



One golden rule I have found is: Always do your analysis first to check whether an existing component can be extended to satisfy your needs. Never give first preference to start from scratch. This is a very simple post and hopefully there has not been any problem till now. The next posts will cover this topic in more detail. Meanwhile try to create a custom Textinput component which has the functionality of clearing the text the moment user clicks inside it. Try using ActionScript.
Hint: We will start with extending Spark Textinput and we will add a mouse click event listener to it in the constructor, just after super call. Then in the corresponding event listener we will set the  text property of this custom component to empty String. Then try to use it at various places and see if it works.

Some good links are (just skim through them):
http://www.ibm.com/developerworks/web/library/wa-flexrendering/
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf684f9-7fff.html

Let me know your feedback and things you would like to be covered.

Saturday, July 14, 2012

Scaling in BlazeDS to support multiple clients

We all know about the messaging limitations for many client in BlazeDS. It can support few hundred clients (documentation mentions few hundred, only god know the exact number).For messaging purpose BlazeDS creates one queue to per client connected to it. It uses one server thread for one client. In BlazeDS if a client is using streaming channel or a long polling with long waiting interval, all available server threads can get blocked and the new client request cannot be fulfilled. In that case the client won't be able to connect. As BlazeDS is servlet based and we can not have a server with thousands of free threads, it becomes a bottleneck while we need to support thousands of clients for messaging. In LCDS, it makes use of NIO based endpoints where it does not use that blocking a thread funds. New servers are coming up with servlet 3.0 specifications and are supposed to resolve this problem.

The following excerpt is taken from here.
Blaze-DS can support hundreds of users (not thousands), this is because the limitation is with its use of Servlet API. An any web-server has limited number of threads. Messaging with Blaze-DS is particularly nasty, as the server will be bombarded with polling requests(as in case of ordinary http polling), or the server threads will be occupied (as in case of long http polling). 

LCDS also has a similar limit. But it supports RTMP, which can be more scalable - but it does not use http, and uses non-standard port (2038?) - this means it will be blocked by firewalls and therefore not usable usually. But for polling requests (ordinary or long polling), it is more scalable than Blaze-DS because it does not use web-server threads for its functioning (instead using what is called Java NIO). Even here, it can support users in thousands (and not in millions etc) - which may be ok. 



You can read about the scaling limitation and work going on in this direction at the following links:

http://blog.hiraash.org/2012/04/13/scaling-blazeds-with-servlet-3-concurrency/
http://www.dan-menard.com/tag/blazeds/



What the hell is that channel and endpoints crap in BlazeDS/LCDS?

Well. this post is a simple explanation about channels and endpoints and what they exactly do. I will not go into all that geeky stuff. In the simplest terms, a channel is a client side object that is needed to talk to server. A channel basically contains (better say encapsulates) the connection behavior and other important properties that are needed to interact with server. An endpoint is corresponding server side code needed for the channel. A channel gets connected to specific endpoint exposed by the server. A channel of type A cannot connect to endpoint of type B, it has to connect to type A only.


<channels>
...
<channel-definition id="samples-amf"
        type="mx.messaging.channels.AMFChannel">
        <endpoint url="http://servername:8400/myapp/messagebroker/amf"
            type="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>


The mapping between channels and endpoints is defined in services-config.xml file situated on server. An example is shown above. We can define multiple channels (channelset) and if one is not available client will fall back to the next in the list.


How channels are assigned to Flex component?
When we compile our application with compiler -service option,  it contains all of the information from the configuration files that is needed for the client to connect to the server. Sometimes developers use this option with Flash builder and think they do not need any channel for their remote object as they are not specifying one. But actually in this case the whole work of mapping and assigning is done internally by Flex.


Otherwise we can create channel manually. It happens generally in the following scenarios:

  • We do not compile our MXML file using the -services MXML compiler option. This is useful when we do not want to hard code endpoint URLs into our compiled SWF files on the client.
  • We want to use a dynamically created destination (the destination is not in the services-config.xml file) with the run-time configuration feature. 
  • We want to control in our client code the order of channels that a Flex component uses to connect to the server.

We can assign the channel to a remote object in MXML and action script. And we all know that. We can read more about it here.

Now we have two main kinds of channels: AMF and HTTP. Actually HTTP channel is by no means connected to HTTP protocol. Even AMF uses HTTP protocol only over TCP.  They both use same http protocol. The main difference is the data transferred over AMF would be binary whereas for HTTP channel it would be in XML format(AMFX format, which is the text-based XML representation of AMF)This channel only exists for customers who require all data sent over the wire to be non-binary for auditing purposes. There is no other reason to use this channel instead of the AMFChannel for RPC-based applications.

There are mainly following type of channels.

Non-polling AMF and HTTP channels

Used for RPC services.

Piggybacking on AMF and HTTP channels
In piggybacking server is not completely dependent on polling of the client at fixed interval. Rather when it receives a non-command message (using a producer ore remote object) , it (server) will send any pending data for client messaging or data management subscriptions along with the response to the client message.

Polling AMF and HTTP channels
Poll the server at fixed interval and get data if any.A polling AMF or HTTP channel is useful when other options such as long polling or streaming channels are not acceptable and also as a fallback channel when a first choice, such as a streaming channel, is unavailable at run time.

Long polling AMF and HTTP channels
It is like polling, but here if client polls a server and does not find any data it won;t come back immediately. Rtaher the request will be parked on the server for some pre-defined time and will come back if data comes or wait time elapses. If wait time is too long it will keep the server thread (blazeds is servlet based and every client uses one thread for it) blocked for long and when all the available server thread are blocked the new clients won't be able to connect. This is primarily a restriction with server, if a server can have 1000 free thread blazeds can support 100 parallel clients.

Streaming channels
Streaming AMF and HTTP channels work with streaming AMF or HTTP endpoints.

This is a brief introduction and more can be read about them here




How to get the time taken by the application to load itself

Hi Friends,

It has been a long time since I posted anything as I was kind of  busy. I am still busy with some project but got time to post some small but useful information. We all know the best practices to reduce the time taken by the SWF to load itself. We can use modules, viewstack (with auto policy), use small sized images (preferably png files), use RSLs etc. But if we want to know whether it has really reduced the time taken to load, how can we find it out?

There is one very simple method for that. We can call the following function on creation complete of application





[Bindable]public var timeTaken:String;

   

public function showInitTime():void{

    timeTaken = "App startup: " + getTimer() + " ms";

}



This variable can be bound to some label



<s:Label text="{timeTaken}"/>



which will display the time taken by the SWF to load itself. I have many such goodies which I have been using and will update. I am also planning to share two of my good components MinimizabePopUP (Spark title window with minimize icon created using spark skin) and BottomDock where the pop-up will be minimized and can be restored from theree. So stay tuned and enjoy!!