I need to connect two Air apps running on different machines, looks like BlazeDS is going to work best for me.  I found this good example, and some code from that is used for the database connection below,  but there don’t seem to be any examples of Air to BlazeDS messaging connection so have posted this, hope it’s useful. You need to have the BlazeDS turnkey installed and running, and the HSQLDB db should be started. The Air app is a ‘vanilla’ project – you don’t need to mess with any J2EE or server settings in Flex when you create the project, all the config is in the AS3. No need to edit anything server side either.
It took a while to figure out how to connect to the messaging service, I’m not sure why the ‘ro2.destination = ‘ line isn’t needed.
Full code after the jump.

<?xml version="1.0" encoding="utf-8"?>
<!--minimal Air example, communication with BlazeDS server database and messaging-->
<!--no extra server config needed inside Flex environment-->
<mx:WindowedApplication
        xmlns:mx="http://www.adobe.com/2006/mxml"
        backgroundColor="#FFFFFF"
        creationComplete="init()" width="837" height="660">
    <mx:Script>
        <![CDATA[
        	import mx.messaging.channels.PollingChannel;
        	import mx.messaging.events.ChannelFaultEvent;
        	import mx.messaging.FlexClient;
        	import mx.rpc.events.FaultEvent;
            import mx.messaging.Channel;
            import mx.messaging.ChannelSet;

            import mx.messaging.channels.AMFChannel;
			import mx.messaging.messages.AsyncMessage;
			import mx.messaging.messages.IMessage;
			import mx.messaging.Consumer;
			import mx.messaging.Producer;
			import mx.messaging.channels.StreamingAMFChannel;
			import mx.messaging.events.MessageEvent;
			import mx.messaging.events.ChannelEvent;
			import mx.messaging.FlexClient;
			import mx.rpc.remoting.RemoteObject;
			import com.carlcalderon.arthropod.Debug;			

			private var producer:Producer = new Producer();
            private var consumer:Consumer = new Consumer();
            private var blazeUrl:String = "http://192.168.1.201:8400/samples/messagebroker/"; //url of turnkey BlazeDS installation
            [Bindable]
			private var ro1:RemoteObject = new RemoteObject();
			private var ro2:RemoteObject = new RemoteObject();

            public function init():void
            {
            	Debug.clear();
	           	ro1.addEventListener(FaultEvent.FAULT, logFault);
            	ro2.addEventListener(FaultEvent.FAULT, logFault);

            	//config db...
                var cs:ChannelSet = new ChannelSet();
                var customChannel:Channel = new AMFChannel("my-amf", blazeUrl + "amf");
                cs.addChannel(customChannel);
                ro1.channelSet = cs;
                ro1.destination = "product";

                //config messages
                ro2.channelSet = cs; //same address as database
                //ro2.destination = "chat-room-service"; //this line not needed, why not?? (maybe defaults...)
                var myStreamingAMF:StreamingAMFChannel = new StreamingAMFChannel("my-streaming-amf", blazeUrl + "streamingamf");
				var myPollingAMF:AMFChannel = new AMFChannel("my-polling-amf", blazeUrl + "amfpolling");
				myPollingAMF.pollingEnabled = true;
				myPollingAMF.pollingInterval = 5000; //set long, so we can see when polling kicks in

				//next line from http://www.dcooper.org/Blog/client/index.cfm?mode=entry&amp;amp;amp;amp;amp;entry=8E1439AD-4E22-1671-58710DD528E9C2E7
				myPollingAMF.piggybackingEnabled = true; //makes quick response for a polling channel, only on sending machine though...
				var channelSet:ChannelSet = new ChannelSet();
				channelSet.addEventListener(ChannelEvent.CONNECT, channelConnected);
				channelSet.addChannel(myStreamingAMF); //looks like need to add streaming first, then polling, else doesn't work
				//channelSet.addChannel(myPollingAMF); //if you add polling, it only ever polls, doesn't stream
				consumer.channelSet = channelSet;
				producer.channelSet = channelSet;
				var name:String= "chat"; //this needs to be 'chat', listed as a destination in BlazeDS 'messaging-config.xml'
				consumer.destination = name;
				producer.destination = name;
				consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);
				consumer.subscribe();
				Debug.log("client id: " + mx.messaging.FlexClient.getInstance().id);
            }

			private function send():void
			{
				Debug.log("send");
				var message:IMessage = new AsyncMessage();
				message.body.chatMessage = msg.text;
				producer.send(message);
				msg.text = "";
			}

			private function messageHandler(e:MessageEvent):void
			{
				Debug.log("receive");
				log.text += e.message.body.chatMessage + "\n";
			}
			private function channelConnected(e:ChannelEvent):void {
				Debug.log(e);
			}
			private function logFault(e:FaultEvent):void{
				Debug.log(e);
			}
        ]]>
    </mx:Script>

    <mx:DataGrid dataProvider="{ro1.getProducts.lastResult}" width="734.1666" height="326.9697"/>
    <mx:Button label="Get Data" click="ro1.getProducts()"/>
	<mx:Panel title="Chat" width="735.4546" height="249.01517">
		<mx:TextArea id="log" width="699.01514" height="162.42424"/>
		<mx:ControlBar>
			 <mx:TextInput id="msg" width="100%" enter="send()"/>
			 <mx:Button label="Send" click="send()"/>
		</mx:ControlBar>
	</mx:Panel>
</mx:WindowedApplication>

3 Responses to “Simple Flex / Air / BlazeDS messaging example”
  1. Tom Stanley says:

    I was on Yahoo and found your blog. Read a few of your other posts. Good work. I am looking forward to reading more from you in the future.

    Tom Stanley

  2. Dominic says:

    Awesome! You have to add the “products” destination for the remoting-config.xml. But they work independently of each other (two destinations), so if one isn’t working (i.e. you didn’t run the sample db startup code), the chat will still function.

    Great job!

    Dominic

  3. Fu di says:

    hi Dominic , it is a message service, the destination should be added in message-config.xml not remoting-config.xml.

  4.  
Leave a Reply


two − 1 =