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!!