BlazeDS Data push with Remote Objects
Now a days, BlazeDS is a pretty well known framework for retrieving data for a flex application. It has even been integrated into a recently released package of Spring. It is an open source, scaled down version of Life Cycle Data Services. It doesn’t have all the glamor as LCDS, but its still 100% useful in most applications.
One of the great features it has taken from LCDS is the ability to support data push. Namely, data push with remote objects, which is great. No more having the client continuously call the server to see if there is new data to be shown. The server is the one who lets the client knows via an httpchannel. So now not only do you get to not have to keep polling, checking for data, but you also get to have remote objects integrated into your application.
This tutorial/how-to is going to include both the serverside of this, as well as the flex side of this. Lets start at the server/environment level. I am going to be honest. I did jack this build.xml (ant is not my strong point right now), everything else is good
. So, first things first. You are going to need a server. I suggest tomcat 6.0x, which can be found here.
I suggest the windows installer to make life easier,but pick which ever works for you. After you install that, download blazeDs:
We are only concerned with the war file in there.

BlazeDs war file
You are going to unzip this into your java web project. The files of concern are going to be the xml files in the Flex directory and the web.xml file. Go ahead and open up the web-inf/web.xml just to clean it up. This isn’t necessary but I get picky sometimes. If you want, rename the display-name and description to whatever you want. After that, you can delete the commented out code. It’s not necessary to keep it there.
Next open up the web-inf/flex/service-config.xml file.
First, in your java project, create a directory called ‘Template’, and make a copy of this file there. Rename it server-config-template.xml. On something like this, I feel its good to have a template you edit and have a build script copy it over. One of those “just in case” things. After you copy it over, I hardcoded the localhost:8080/BlazeDsServer for the server.name:server.port/contextroot part. More importantly, you are going to add this to it.
<channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel"> <endpoint url="https://localhost:8080/BlazeDsServer/messagebroker/amfsecure/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint" /> <properties> <idle-timeout-minutes>0</idle-timeout-minutes> <max-streaming-clients>10</max-streaming-clients> <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis> <user-agent-settings> <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="3" /> <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="3" /> </user-agent-settings> </properties> </channel-definition>
This is going to add steaming to our service. Pretty straight forward. After you have added that, go ahead and save it. Our service-config-template.xml should look like this now:
<?xml version="1.0" encoding="UTF-8"?> <services-config> <services> <service-include file-path="remoting-config.xml" /> <service-include file-path="proxy-config.xml" /> <service-include file-path="messaging-config.xml" /> </services> <security> <login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat"/> </security> <channels> <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://localhost:8080/BlazeDsServer/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel"> <endpoint url="https://localhost:8080/BlazeDsServer/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/> <properties> <add-no-cache-headers>false</add-no-cache-headers> </properties> </channel-definition> <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel"> <endpoint url="https://localhost:8080/BlazeDsServer/messagebroker/amfsecure/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint" /> <properties> <idle-timeout-minutes>0</idle-timeout-minutes> <max-streaming-clients>10</max-streaming-clients> <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis> <user-agent-settings> <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="3" /> <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="3" /> </user-agent-settings> </properties> </channel-definition> <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://localhost:8080/BlazeDsServer/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/> <properties> <polling-enabled>true</polling-enabled> <polling-interval-seconds>4</polling-interval-seconds> </properties> </channel-definition> </channels> <logging> <target class="flex.messaging.log.ConsoleTarget" level="Error"> <properties> <prefix>[BlazeDS] </prefix> <includeDate>false</includeDate> <includeTime>false</includeTime> <includeLevel>false</includeLevel> <includeCategory>false</includeCategory> </properties> <filters> <pattern>Endpoint.*</pattern> <pattern>Service.*</pattern> <pattern>Configuration</pattern> </filters> </target> </logging> <system> <redeploy> <enabled>false</enabled> </redeploy> </system> </services-config>
Next, open up messaging-config.xml. Now, we are going to create this adapter soon, but lets go ahead and add the reference while we are here. Add the following line to the top but within the service tag.
<adapters> <adapter-definition id="BlazeDsServicePushAdapter" class="com.codeofdoom.BlazeDsServiceAdapter"/> </adapters>
This is going to be the adapter that retrieves the data for us. You are allowed to leave the other adapter in there if you want, but its not necessary.
Next we are going to add our destination. This is what our flex application will be pointing to in order to consume the data. Add this to the messaging-config.xml:
<destination id="BlazeDsServicePush"> <channels> <channel ref="my-streaming-amf" /> </channels> <adapter ref="BlazeDsServicePushAdapter"/> </destination>
Here we give our destination a channel. Our channel was added in our services-config.xml and we are telling our destination to use the my-streaming-amf channel. Next we then tell it to use the adapter we just defined at the top. After you have added, go ahead and save that file.
Since this is a tutorial about remote-objects, we are going to have to create those too. So I created this:
package com.codeofdoom; public class Person { private String firstName; private String lastName; private Integer age; public Person(String firstName, String lastName, Integer age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public Person(){} public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Just a standard pojo and nothing more. We are going to create something similar on the flex side soon, but lets create out service adapter next. Check it out.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package com.codeofdoom; import java.util.ArrayList; import java.util.List; import java.util.Random; import flex.messaging.MessageBroker; import flex.messaging.messages.AsyncMessage; import flex.messaging.messages.Message; import flex.messaging.services.MessageService; import flex.messaging.services.ServiceAdapter; import flex.messaging.util.UUIDUtils; public class BlazeDsServiceAdapter extends ServiceAdapter { Random random; PersonGenerator thread; public BlazeDsServiceAdapter(){ random = new Random(); System.out.println("Adapter initilized"); } public void start(){ if(thread == null){ System.out.println("Adapter started"); thread = new PersonGenerator(); thread.start(); } } public void stop(){ System.out.println("Adapter stopped"); thread.running = false; thread=null; } private List<Person> generatePersons(){ List<Person> arr = new ArrayList<Person>(); for (int x=0;x<5;x++){ Person p = new Person(); p.setFirstName("FirstPerson"+x); p.setLastName("LastPerson"+x); p.setAge(random.nextInt(80)); arr.add(p); } return arr; } public class PersonGenerator extends Thread { public boolean running = true; public void run(){ String clientId = UUIDUtils.createUUID(); MessageBroker msgBroker = MessageBroker.getMessageBroker(null); while (running){ AsyncMessage msg = new AsyncMessage(); msg.setDestination("BlazeDsServicePush"); msg.setClientId(clientId); List <Person>a= generatePersons(); msg.setMessageId(UUIDUtils.createUUID()); msg.setBody(a); msgBroker.routeMessageToService(msg,null); try{ Thread.sleep(5000); }catch(InterruptedException e){ System.out.println("Exception"); e.printStackTrace(); } } } } @Override public Object invoke(Message msg) { if(msg.getBody().equals("New")){ System.out.println("Adapter received new"); return generatePersons(); }else{ System.out.println("Adapter sending message"); AsyncMessage newMessage = (AsyncMessage)msg; MessageService msgService = (MessageService)getDestination().getService(); msgService.pushMessageToClients(newMessage, true); } return null; } } |
Few key things about this class. First, it extends ServiceAdapter. This is part of the flex messaging service. The part this affects is the invoke method. This is where our messages get sent out to our front end. To see where its getting this data from, look at the PersonGenerator class. This is the thread that is running that will create new data for us every 5 seconds. Most important part of this class is where you are setting the messages destination. Once again, the destination is what our flex side has the open httpservice on.
After that is called and its sent to the message broker, the invoke method picks that up and then fires it off to the front end. So, after that lovely explanation, lets make sure it actually builds and deploys. Right click on the build.xml file and select run as > ant build. It should create a dist directory in your java project, and in there is a war file called BlazeDsServer.war. Once tomcat is running, take that war file and drop it into your webapps directory. You should see a BlazeDsServer directory get created. Also if you look to your logs, you should see something like this, indicated the application has started.

Application starting in tomcat
Now lets setup our flexproject. After creating a standard Flex project, we need to point our flex compile options to point to the services-confg.xml file. If you right click your flex project and go to properties, then flex compiler. Under additional compiler arguments, add this line
-compiler.services “%SERVICES-CONFIG-PATH% \services-config.xml”
Of course, you are going to want to set your %SERVICES-CONFIG-PATH% to whatever directory your file is residing.

Flex Compiler
After that, we need to create our mirrored remote object. All properties must be the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package com.codeofdoom.dto { [Bindable] [RemoteClass(alias="com.codeofdoom.Person")] public class Person { private var _firstName:String; private var _lastName:String; private var _age:Number; public function Person(){ } public function get firstName():String{ return _firstName; } public function get lastName():String{ return _lastName; } public function get age():Number{ return _age; } public function set firstName(firstName:String):void{ _firstName = firstName; } public function set lastName(lastName:String):void{ _lastName = lastName; } public function set age(age:Number):void{ _age = age; } } } |
There you go. PLEASE NOTE SOMETHING. I ran into a horrible snag while learning this. Maybe this is a work around, maybe there isn’t, but I ran into horrible problems with this trying to have a constructor with arguments. Normally it would just tell you it expected 3 arguments, got 0. However, in this instance, it swallowed the error and I wouldn’t get my objects back. So PLEASE be careful!. Also you must declare the object as both Bindable and as a RemoteClass, pointing to the fully qualified name (path+classname).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.messaging.messages.IMessage; import mx.messaging.events.MessageAckEvent; import mx.messaging.messages.AsyncMessage; import mx.messaging.events.MessageEvent; import com.codeofdoom.dto.Person; private function init():void{ var message:AsyncMessage = new AsyncMessage(); message.body = "New"; producer.send(message); consumer.subscribe(); } private function onMsg(event:MessageEvent):void{ grid.dataProvider = event.message.body as ArrayCollection; } private function pub():void { var message:AsyncMessage = new AsyncMessage(); message.body = "New"; producer.send(message); } private function ack(event:MessageAckEvent):void{ grid.dataProvider = event.message.body as ArrayCollection; } ]]> </mx:Script> <mx:Producer id="producer" destination="BlazeDsServicePush" acknowledge="ack(event)"/> <mx:Consumer id="consumer" destination="BlazeDsServicePush" message="onMsg(event)"/> <mx:VBox> <mx:DataGrid id="grid"> <mx:columns> <mx:DataGridColumn dataField="firstName" headerText="First Name"/> <mx:DataGridColumn dataField="lastName" headerText="Last Name"/> <mx:DataGridColumn dataField="age" headerText="Age"/> </mx:columns> </mx:DataGrid> </mx:VBox> </mx:Application> |
As for our mxml, its just going to be a simple grid that will display the first name, last name and the age of the person. The key parts are the producer and consumer. Normally we would only need a consumer, but I wanted to put the producer in there for a reason. Lets say that our interval for new data was 5 minutes vs 5 seconds. With our thread running, we might log in 1 second after the last one was fired off. However, we first send have our producer request new data. This is only a 1 time thing in our application, but in a real world situation, you aren’t going to let your customers wait 5 minutes for data.
Both our consumer and our producer are pointed to BlazeDsServicePush. Lastly, our init function fires off. Here we send the service our initial “give me data” message from the producer. Then our consumer subscribes to that destination. After that, you are ready to retrieve data
. Your output should look something like this:

There are many applications where time sensitive data is important to the end user. In this scenario, you have two choices. Have the client continuously poll the server, saying ‘new data yet? New data yet? New data yet?’ OR you can just have the client sitting pretty and just have the back end tell it when the new data is there. If you arent getting data, a good place to check is your tomcat logs. When you start up your flex application, you should see a line that says “Adapter received new”
If you do run into any snagging getting your backend to compile or run or build or whatever, please feel free to leave questions. It can definitely be something tricky. Luckily for you, I have included the source. Enjoy!
Here is the source.
Nice article! However, you should note that the streaming-amf channel doesn’t scale too well with a lot of clients. If you have a lot of clients, you still need to use LCDS.
how can i get data from database using context bean because it invoked when server started as before the bean and session factory gets created i am unable to get the data using bean from applicationcontext.xml
do some favour for me as soon as possible
Thanks for the Example, however i fail to understand what good is creating a RemoteObject if you receive it in the other side (in this case the flex app) like a plain old object.
I was expecting that i could do something like
var a:Person= event.message.body as Person;
instead of just placing it into an ArrayCollection. Can this be done?
Yes you can do that as well. If your applications calls for that, you can easily do that. I just put it in an ArrayCollection in order to use it as a dataprovider for the grid.
Hope this helps!
Thanks for the reply Marcel, I’ve tried that but no joy. I get “a” as NULL. Im doing the whole RemoteObject thing. If you can point to an example you will earn a beer if you are ever in Guatemala
Are you able to inspect your object in debug mode on the flex side to see what is coming back? I dont have the code in front of me so I cant check. Also are you casting it as a String? Are you changing the service not to return a List?
Great tutorial, thanks.
FYI – Line 17 of services-config-template.xml needs {client.host} replaced with hard coded localhost.
Regarding Alejandro’s post… The contents of Flex’s ArrayCollection will be of type “Person”. It can be hard to tell this in the debugger, but it if you cast an item in the collection to Person you’ll see. I wasn’t able to return a single Person instance successfully using messaging, but I do it all the time with direct Remoting. I’ll show you how if you haven’t figured out already.
I’ll want a beer in Guatemala too though…
Hello,
I’ve tested your tutorial. All is perfect but … when I launch the application, it doesn’t work. The fault is :
——————————-
[MessageFaultEvent faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: 'http://localhost:8080/blazeds/messagebroker/amfsecure/streamingamf'" faultString="Send failed" rootCause=[ChannelFaultEvent faultCode="Channel.Connect.Failed" faultString="error" faultDetail="NetConnection.Call.Failed: HTTP: Failed: url: 'http://localhost:8080/blazeds/messagebroker/amfsecure/streamingamf'" channelId="my-streaming-amf" type="channelFault" bubbles=false cancelable=false eventPhase=2] type=”fault” bubbles=false cancelable=false eventPhase=2]
————————
I’ve defined the channel my-streaming-amf like you in the services-config.xml.
Have you an idea of what it happens?
Thank you for your answer
@Softyne
My first assumption would be that you arent running your web service. Is tomcat running and have you deployed the war file?
If so, then i would suggest checking firewalls or anything that might be blocking it (although you are just local. im thinking out loud). But check your tomcat/webapps directory for a blazeds folder.
just my guess.
package com.codeofdoom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import flex.messaging.MessageBroker;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.messages.Message;
import flex.messaging.services.MessageService;
import flex.messaging.services.ServiceAdapter;
import flex.messaging.util.UUIDUtils;
public class BlazeDsServiceAdapter extends ServiceAdapter
{
Random random;
PersonGenerator thread;
public BlazeDsServiceAdapter()
{
random = new Random();
System.out.println(”Adapter initilized”);
}
public void start()
{
if(thread == null)
{
System.out.println(”Adapter started”);
thread = new PersonGenerator();
thread.start();
}
}
public void stop()
{
System.out.println(”Adapter stopped”);
thread.running = false;
thread=null;
}
private List generatePersons()
{
List arr = new ArrayList();
for (int x=0;x<5;x++)
{
Person p = new Person();
p.setFirstName(”FirstPerson”+x);
p.setLastName(”LastPerson”+x);
p.setAge(random.nextInt(80));
arr.add(p);
}
return arr;
}
public class PersonGenerator extends Thread
{
public boolean running = true;
public void run()
{
String clientId = UUIDUtils.createUUID();
MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
while (running)
{
AsyncMessage msg = new AsyncMessage();
msg.setDestination(”BlazeDsServicePush”);
msg.setClientId(clientId);
List a= generatePersons();
msg.setMessageId(UUIDUtils.createUUID());
msg.setBody(a);
msgBroker.routeMessageToService(msg,null);
try
{
Thread.sleep(5000);
}
catch(InterruptedException e)
{
System.out.println(”Exception”);
e.printStackTrace();
}
}
}
}
@Override
public Object invoke(Message msg)
{
if(msg.getBody().equals(”New”))
{
System.out.println(”Adapter received new”);
return generatePersons();
}
else
{
System.out.println(”Adapter sending message”);
AsyncMessage newMessage = (AsyncMessage)msg;
MessageService msgService = (MessageService)getDestination().getService();
msgService.pushMessageToClients(newMessage, true);
}
return null;
}
}
when server will start it will start pushing data but in invoke() method its going to else loop it not cating the published msg plz can any one suggest solution
public Object invoke(Message msg)
{
if(msg.getBody().equals(”New”))
{
System.out.println(”Adapter received new”);
return generatePersons();
}
else
{
System.out.println(”Adapter sending message”);
AsyncMessage newMessage = (AsyncMessage)msg;
MessageService msgService = (MessageService)getDestination().getService();
msgService.pushMessageToClients(newMessage, true);
}
return null;
}
}
it not displaying in datagrid
<endpoint url=”https://localhost:8080/BlazeDsServer/messagebroker/amfsecure/streamingamf
If this is ever going to get deployed in real life, what url would you use? If the client downloads this .swf file you would have to hardcode in the exact server name correct? How do you get around this? You aren’t always going to know the exact server url the .war gets deployed on.
This is the reason Flex is not a viable option to me to ever use in real life.
@testerman
I think you are getting confused by the localhost thing. I blame myself for being lazy since I just hardcoded it. Getting a good ant script working was not part of what I wanted to do.
I have worked on many enterprise level flex applications with blazeDS and I assure you it is a viable option, a few using BlazeDS. Normally you would have an ant script that allowed it to read from pre configured properties files. This way whoever builds your war will be allowed to setup whatever ip you want.
Hope that helps.
I recently looked into Flex and BlazeDS with a Grails back end (using the flex plugin). The services-config.xml file I had used tokens {server.name}, {server.port} and {context.root}. The only one I had to hard code at flex compile time was the context root. I compiled the flex client on one machine (having copied the xml file to that machine) and then deployed the swf onto Tomcat (inside a grails app) on another machine and it just worked. I did not need to set (or read in) the server IP or port number. I believe that as long as your flex client wants to talk to the same server from which it was served then it does not require a server IP to be specified (also not requiring a cross domain policy file).
Deleting items by Drag and Drop + flex
That really cool example, awesome Marcel!
Hello
Wich program you use to create service adapter ? Java IDE can support import flex.messaging.MessageBroker ? I try Eclipse , IntelliJ IDEA 9 and dont have option to import flex.messaging.MessageBroker
thank you
One thing I noticed when doing server push with BlazeDS is that I can easily make my browser crash by pushing large files (such as images) over the pipe and then closing my browser without ending the flash connection. The java server keeps pushing and building up a queue then eventually runs out of memory and crashes. Have you seen similar behavior?
I have implemented the above example and it is working fine in Miscrosoft Internet Explorer but it is not working in Mozilla Firefox. Anybody have any solution to resolve this issue.
Hello,
I installed the application successfully on eclipse.
Every thing is fine except that when i run my client , the producer fails to send the “New” message.
-Is their something else to add in the configuration files?
Regards
i’ve got the problem:
You should change the project context root:
1- right click on your project.
2- choose “properties”
3- choose “flex server”
4- Edit the context root with /yourProjectName
5- then save changes
=> execution and every thing should run successfully
PS:
instead of “http://localhost:8080/BlazeDsServer/”, copy/paste this “https://{server.name}:{server.port}/{context.root}/”
Because in “reallife” server name, port and context root are not constantes, that’s why they should be parametred.
=>don’t applicate the PS section if you don’t want to, it’s not necessary.
@Ishwar
The reason Firefox does not work in this example is that the “https” protocol is used in the endpoint URL, but the non-secure StreamingAMFChannel and StreamingAMFEndpoint classes are defined. I’m not sure why IE does work though…
To fix, either:
1) Use ‘http’ instead of ‘https’.
OR
2) Use SecureStreamingAMFChannel and SecureStreamingAMFEndpoint.
work. good
tomcat 6.0.18 + java 1.5 very well gracias
Hi,
I have done everything right and im able to get an ArrayCollection back. However, when im trying to access the object inside the ArrayCollection by typecasting it, im not getting anything. See the code snippet below;
reportCollec = ArrayCollection(event.result);
resultGrid.dataProvider = reportCollec;
var rep:Report = Report(reportCollec.getItemAt(0, 0));
Alert.show(rep.get_Domain());
Though i’m able to see the values in a dataGrid, when i trying to access individual Report object from the ArrayCollection, im not getting anything. Could you let me know any possible ways to fix this behaviour?
This is a very good example.
One question. Is there a way to send different messages to different clients? Suppose you want to use a streaming connection without the consumer/producer model, how would you only selectively stream updates to a particular client ?
The web is overflowing with thesis service and thesis research referring to this topic though to get really great buy dissertation service, some students can use some hints.
Hello,
Nice article! It helped me a lot.How can we achieve this by taking the consumer id as a request parameter for example, a module which gets & displays the messages that you got from the friends( for all the consumers who were logged into the application currently).
Am trying to set the consumer id as part of the AsyncMessage body, as shown below
var message:AsyncMessage = new AsyncMessage();
//message.body = “New”;
var consumerRequestObject:Object = new Object();
consumerRequestObject.consumerId = consumerId;
message.body = consumerRequestObject;
producer.send(message);
and i don’t know exactly where to make changes in the business logic of invoke() and in other places of ServiceAdapter class.
Hope understood the problem & hoping that some one will help me in this.Any help would be appreciated!!!.
If you need more information about this requirement, please feel free to drop me a mail(yuvarajsingh2020@yahoo.com).
Thanks
Sankar Kethineni.
Hi,
It indeed is a nice article.
Can you please also demonstrate if we want to use Spring-Blazeds integration for the same purpose, what will be the changes to be done in spring context file? (Because messaging-config.xml will no longer exist)
Miral