Lab 1 - Be a message consumer
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
applicationComplete="init()" viewSourceURL="srcview/index.html">
<!--How to subscribe to a topic and trace consumer feed to console. Need to have a destination setup in
messaging config called helloWorld under lcds-samples/WEB-INF/flex. -->
<mx:Script>
<![CDATA[
import mx.messaging.events.MessageEvent;
import mx.controls.Alert;
private function init():void
{
this.consumer.subscribe();
}
private function messageHandler(event:MessageEvent):void
{
log.text += event.message.body.chatMessage + "\n";
}
]]>
</mx:Script>
<mx:ChannelSet id="channelSet">
<mx:AMFChannel url="http://192.168.1.50:8400/lcds-samples/messagebroker/amflongpolling"/>
</mx:ChannelSet>
<mx:Consumer id="consumer"
channelSet="{channelSet}"
destination="helloWorld"
message="messageHandler(event)"
fault="Alert.show(event.faultDetail)"/>
<mx:Panel title="Data Feed" width="100%" height="100%">
<mx:TextArea id="log" width="100%" height="100%" editable="false"/>
</mx:Panel>
</mx:Application>
Lab 2 - Be a message producer
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()">
<!--How to send a message to a topic as a producer of the message. Should see message sent on big screen.
Need to have a destination setup in messaging config called helloWorld under lcds-samples/WEB-INF/flex. -->
<mx:Script>
<![CDATA[
import mx.messaging.events.MessageEvent;
import mx.messaging.messages.AsyncMessage;
import mx.controls.Alert;
private function init():void
{
// Start listening for messages published in the "helloWorld" destination
consumer.subscribe();
}
private function messageHandler(event:MessageEvent):void
{
log.text += event.message.body.chatMessage + "\n";
}
// Add a send method to send the message as the producer
private function send():void
{
var message:AsyncMessage = new AsyncMessage();
// Set the term chatMessage for the body
message.body.chatMessage = msg.text;
producer.send(message);
msg.text = "";
}
]]>
</mx:Script>
<mx:ChannelSet id="channelSet">
<mx:AMFChannel url="http://192.168.1.50:8400/lcds-samples/messagebroker/amflongpolling"/>
</mx:ChannelSet>
<mx:Consumer id="consumer"
channelSet="{channelSet}"
destination="helloWorld"
message="messageHandler(event)"
fault="Alert.show(event.faultString)"/>
<!-- Add a producer to send messages -->
<mx:Producer id="producer"
channelSet="{channelSet}"
destination="helloWorld"/>
<mx:Panel title="Data Feed" width="100%" height="100%">
<mx:TextArea id="log" width="100%" height="100%" editable="false"/>
<mx:ControlBar>
<mx:TextInput id="msg" width="100%" enter="send()"/>
<mx:Button label="Send" click="send()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
Lab 3 - Subscribe to real-time data
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
<mx:Script>
<![CDATA[
import mx.messaging.events.MessageEvent;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
[Bindable]
private var feedItems:ArrayCollection = new ArrayCollection();
private function init():void
{
this.consumer.subscribe();
}
private function messageHandler(event:MessageEvent):void
{
feedItems.addItem(event.message.body);
}
]]>
</mx:Script>
<!-- The destination can be accessed using four different channels: RTMP, AMF Streaming, AMF Long Polling, AMF Polling.
You can choose which channel(s) to use to access the destination: just comment out the channels you don't want to use.
For example, if you don't want a dependency on fds.swc, uncomment the RTMP channel definition. The order of the channels
defined in the ChannelSet tag is important: The system will try to connect using the first one. If that connection fails,
it will fall back to the next one, etc. In real life, these URLs shouldn't be hardcoded in the application... One option
is to use a configuration file as described here:
http://coenraets.org/blog/2009/03/externalizing-service-configuration-using-blazeds-and-lcds/-->
<mx:ChannelSet id="channelSet">
<!-- RTMP channel -->
<!--<mx:RTMPChannel id="rtmp" url="rtmp://tourdeflex.adobe.com:2037"/>-->
<!-- Long Polling Channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amflongpolling"/>
<!-- Regular polling channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amfpolling"/>
</mx:ChannelSet>
<mx:Consumer id="consumer"
channelSet="{channelSet}"
destination="tdf.sampleviewingfeed"
subtopic="flex"
message="messageHandler(event)"
fault="Alert.show(event.faultString)"/>
<mx:Panel title="Data Feed" width="100%" height="100%">
<mx:DataGrid id="dg" dataProvider="{feedItems}" width="100%" height="100%"/>
</mx:Panel>
</mx:Application>
Lab 4 - Use Flex charting with real-time data
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()"
viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.messaging.events.MessageEvent;
import mx.controls.Alert;
[Bindable]
private var feedItems:ArrayCollection = new ArrayCollection();
private var keys:Dictionary = new Dictionary();
private var countryArray:Array = new Array();
private function init():void
{
this.consumer.subscribe();
}
/**
* This filter function is used to see if the country item in the array has already had hits.
* If it has then we need to accumulate the hit count, otherwise we need to add it to the
* data provider with hit count 1.
**/
private function accumulateHits(item:Object, idx:uint, arr:Array):Boolean
{
// 'keys' will contain each country code as the key and the item object (CountryVO) as the value, which
// contains both country and hits amount.
if (keys[item.country]!=null) {
// Update the hits count for the item
item.hits = item.hits+=1;
return false;
} else {
item.hits=1;
keys[item.country] = item;
feedItems.addItem(item);
return true;
}
}
private function messageHandler(event:MessageEvent):void
{
var country:String = event.message.body.country;
var co:CountryVO = new CountryVO();
co.country=country;
// Add this to an array and call a filter function to check if that country has already
// had hits detected.
countryArray.push(co);
countryArray.filter(accumulateHits);
}
]]>
</mx:Script>
<!-- The destination can be accessed using four different channels: RTMP, AMF Streaming, AMF Long Polling, AMF Polling.
You can choose which channel(s) to use to access the destination: just comment out the channels you don't want to use.
For example, if you don't want a dependency on fds.swc, uncomment the RTMP channel definition. The order of the channels
defined in the ChannelSet tag is important: The system will try to connect using the first one. If that connection fails,
it will fall back to the next one, etc. In real life, these URLs shouldn't be hardcoded in the application... One option
is to use a configuration file as described here:
http://coenraets.org/blog/2009/03/externalizing-service-configuration-using-blazeds-and-lcds/-->
<mx:ChannelSet id="channelSet">
<!-- RTMP channel -->
<!--<mx:RTMPChannel id="rtmp" url="rtmp://tourdeflex.adobe.com:2037"/>-->
<!-- Long Polling Channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amflongpolling"/>
<!-- Regular polling channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amfpolling"/>
</mx:ChannelSet>
<mx:Consumer id="consumer"
channelSet="{channelSet}"
destination="tdf.sampleviewingfeed"
subtopic="flex"
message="messageHandler(event)"
fault="Alert.show(event.faultString)"/>
<mx:VBox width="100%" height="100%">
<mx:Legend dataProvider="{bar}"/>
<mx:BarChart id="bar" height="70%" showDataTips="true" dataProvider="{feedItems}">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="country"/>
</mx:horizontalAxis>
<mx:series>
<mx:BarSeries xField="country" yField="hits" displayName="Hits per Country"/>
</mx:series>
</mx:BarChart>
<mx:HBox>
<mx:ColumnChart id="col" showDataTips="true" dataProvider="{feedItems}">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="country"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="country" yField="hits"/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{pie}" />
<mx:PieChart id="pie" showDataTips="true" dataProvider="{feedItems}">
<mx:series>
<mx:PieSeries field="hits" nameField="country" labelPosition="insideWithCallout"/>
</mx:series>
</mx:PieChart>
</mx:HBox>
</mx:VBox>
</mx:Application>
Lab 4 - CountryVO.as
package
{
[Bindable]
public class CountryVO
{
public var country:String;
public var hits:Number;
}
}
Lab 5 - Visualization and mapping
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:maps="com.google.maps.*" layout="absolute" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import com.google.maps.Map3D;
import com.google.maps.LatLng;
import com.google.maps.MapEvent;
import com.google.maps.overlays.Marker;
import com.google.maps.MapType;
import com.google.maps.MapOptions;
import mx.messaging.messages.IMessage;
import com.google.maps.controls.MapTypeControl;
import com.google.maps.controls.NavigationControl;
import com.google.maps.View;
import com.google.maps.geom.Attitude;
import com.google.maps.InfoWindowOptions;
private var flyToFlag:Boolean = false;
private var infoWindowFlag:Boolean = false;
private var flightSpeed:Number = 3;
private var initialZoom:Number = 2.5;
private var flyToZoom:Number = 5;
private var initialLat:Number = 25;
private var initialLong:Number = 10;
private var initialAttitude:Attitude = new Attitude(0,0,0);
private var flyToAttitude:Attitude = new Attitude(20,30,0);
private function onMapPreinitialize(event:MapEvent):void
{
var myMapOptions:MapOptions = new MapOptions();
myMapOptions.zoom = initialZoom;
myMapOptions.center = new LatLng(initialLat, initialLong);
myMapOptions.mapType = MapType.PHYSICAL_MAP_TYPE;
myMapOptions.viewMode = View.VIEWMODE_PERSPECTIVE;
myMapOptions.attitude = initialAttitude;
map.setInitOptions(myMapOptions);
}
private function onMapReady():void
{
map.addControl(new MapTypeControl());
map.addControl(new NavigationControl());
// The map is good to go, let's subscribe to the messages
consumer.subscribe();
}
private function toggleFlyTo():void
{
if(flyToFlag)
{
map.cancelFlyTo(); // Stop any current flyTo motion
map.flyTo(new LatLng(initialLat, initialLong), initialZoom, initialAttitude, 5);
}
flyToFlag = flyToCheckBox.selected;
}
private function toggleInfoWindow():void
{
infoWindowFlag = infoWindowCheckBox.selected;
}
private function messageHandler(message:IMessage):void
{
var latlng:LatLng = new LatLng(message.body.latitude, message.body.longitude);
if(latlng != null)
{
var marker:Marker = new Marker(latlng);
if(flyToFlag) map.flyTo(latlng, flyToZoom, flyToAttitude, flightSpeed);
if(infoWindowFlag) map.openInfoWindow(latlng, new InfoWindowOptions({title: message.body.city, content: "Sample ID:" + message.body.sampleId + " viewed"}));
map.addOverlay(marker);
}
}
]]>
</mx:Script>
<mx:ChannelSet id="channelSet">
<!-- RTMP channel -->
<!--<mx:RTMPChannel id="rtmp" url="rtmp://tourdeflex.adobe.com:2037"/>-->
<!-- Long Polling Channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amflongpolling"/>
<!-- Regular polling channel -->
<mx:AMFChannel url="http://tourdeflex.adobe.com:8080/lcds-samples/messagebroker/amfpolling"/>
</mx:ChannelSet>
<mx:Consumer id="consumer"
channelSet="{channelSet}"
destination="tdf.sampleviewingfeed"
subtopic="flex"
message="messageHandler(event.message)"
fault="Alert.show(event.faultString)"/>
<maps:Map3D id="map" mapevent_mappreinitialize="onMapPreinitialize(event)"
mapevent_mapready="onMapReady()"
width="100%" height="100%" key=""/> <!-- API key not needed when running from localhost -->
<mx:VBox x="100" y="5">
<mx:Label fontSize="18" fontWeight="bold" text="Tour de Flex Live Traffic" right="60" />
<mx:CheckBox id="flyToCheckBox" fontWeight="bold" label="FlyTo (animated 3D flight)" click="toggleFlyTo()"/>
<mx:CheckBox id="infoWindowCheckBox" fontWeight="bold" label="Info Window" click="toggleInfoWindow()"/>
</mx:VBox>
</mx:Application>