<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
horizontalAlign="left"
width="100%"
height="100%"
creationComplete="onCreationComplete(event)"
viewSourceURL="srcview/index.html"
>
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.messaging.Channel;
import mx.messaging.events.ChannelEvent;
import flash.net.registerClassAlias;
import mx.rpc.remoting.mxml.RemoteObject;
import weborb.messaging.WeborbProducer;
import mx.messaging.messages.AsyncMessage;
import mx.messaging.ChannelSet;
import weborb.messaging.WeborbMessagingChannel;
import weborb.messaging.WeborbConsumer;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.messaging.events.MessageFaultEvent;
import mx.messaging.events.MessageAckEvent;
import mx.messaging.events.MessageEvent;
import mx.messaging.events.ChannelFaultEvent;
import mx.events.FlexEvent;
[Bindable]
private var producer:WeborbProducer;
[Bindable]
private var consumer:WeborbConsumer;
[Bindable]
private var wOrb_nc:NetConnection;
[Bindable]
private var channel:WeborbMessagingChannel;
[Bindable]
private var cs:ChannelSet;
[Bindable]
private var clientId:String;
private const ENDPOINT:String = "http://localhost/johleromsmq/weborb.aspx";
private const URI:String = "rtmp://localhost:2037/MessagingService";
private const REMOTEDESTINATION:String = "GenericDestination";
private const MESSAGINGDESTINATION:String = "JohleroMsmqChannel"
private const NETCONNECTIONSUCCESS:String = "NetConnection.Connect.Success";
private const MANAGEMENTSERVICE:String = "Weborb.Management.ManagementService";
/**
* Application creationComplet handler
*/
public function onCreationComplete(event:FlexEvent) : void
{
this.addLogMessage("onCreationComplete");
registerClassAlias("Messaging.Messages.LockedAppleMessage", LockedAppleMessage);
registerClassAlias("Messaging.Messages.LockedPotatoeMessage", LockedPotatoeMessage);
registerClassAlias("Messaging.Messages.LockedBananaMessage", LockedBananaMessage);
this.createChannelSet();
}
/**
* Result handler for pinging WebORB
*/
private function onWebOrbPingResult(result:ResultEvent) : void
{
this.addLogMessage("onWebOrbPingResult(" + result.toString() + ")");
this.initConnectionButton.enabled = true;
this.makeButtonGreen(this.pingWebOrbButton);
}
/**
* Fault handler for pinging WebORB
*/
private function onWebOrbPingFault(fault:FaultEvent) : void
{
this.addLogMessage("onWebOrbPingFault(" + fault.toString() + ")");
this.makeButtonRed(this.pingWebOrbButton);
}
/**
* NetConnection Status Event
*/
private function netStatusHandler(event:NetStatusEvent) : void
{
this.addLogMessage("netStatusHandler(" + event.info.code.toString() + ")");
this.netConnectionCheckBox.selected = wOrb_nc.connected;
switch (event.info.code) {
case NETCONNECTIONSUCCESS:
this.makeButtonGreen(this.initConnectionButton);
break;
default:
this.makeButtonRed(this.initConnectionButton);
break;
}
}
/**
* NetConnection security error handler
*/
private function securityErrorHandler(event:SecurityErrorEvent) : void
{
this.addLogMessage("securityErrorHandler(" + event.toString() + ")");
this.makeButtonRed(this.initConnectionButton);
}
/**
* Channel Message handler
*/
private function onChannelMessage(event:MessageEvent) : void
{
this.addLogMessage("onChannelMessage(" + event.toString() + ")");
if(event.message.body is LockedPotatoeMessage)
{
this.addLogMessage("LockedPotatoeMessage arrived: " + event.message.body.toString());
}
else if(event.message.body is LockedBananaMessage)
{
this.addLogMessage("LockedBananaMessage arrived: " + event.message.body.toString());
}
else if(event.message.body is LockedAppleMessage)
{
this.addLogMessage("LockedAppleMessage arrived: " + event.message.body.toString());
}
else
{
this.addLogMessage("Unknown Message");
}
}
/**
* Channel is connected.
*/
private function onChannelConnect(event:ChannelEvent) : void
{
this.addLogMessage("onChannelConnect(" + event.toString() + ")");
this.channelVBox.setStyle("backgroundColor", 0x3EFA04);
}
/**
* Channel is disconnected.
*/
private function onChannelDisconnect(event:ChannelEvent) : void
{
this.addLogMessage("onChannelDisconnect(" + event.toString() + ")");
this.channelVBox.setStyle("backgroundColor", 0xFF0000);
}
/**
* Fault while connecting.
*/
private function onChannelFault(event:ChannelEvent) : void
{
this.addLogMessage("onChannelFault(" + event.toString() + ")");
this.channelVBox.setStyle("backgroundColor", 0xFF0000);
}
/**
* Channel of Consumer successfully connected.
*/
private function onConsumerMessageAck(event:MessageAckEvent) : void
{
this.addLogMessage("onConsumerMessageAck(" + event.toString() + ")");
this.makeButtonGreen(this.connectConsumerButton);
}
/**
* If Channel of the Consumer can't connect, then this Fault is triggered together
* with the onChannelFault. I guess behind the screens these two Fault events are the same, or better,
* the MessageFaultEvent contains the ChannelEvent from the onChannelFault event.
*/
private function onConsumerMessageFault(event:MessageFaultEvent) : void
{
this.addLogMessage("onConsumerMessageFault(" + event.toString() + ")");
this.makeButtonRed(this.connectConsumerButton);
}
/**
* Channel of the Producer successfully connected.
*/
private function onProducerMessageAck(event:MessageAckEvent) : void
{
this.addLogMessage("onProducerMessageAck(" + event.toString() + ")");
this.makeButtonGreen(this.connectProducerButton);
}
/**
* If the Channel of the Producer can't connect, then this Fault is triggered together with the
* onChannelFault. I guess behind the screens these two Fault events are the same, or better,
* the MessageFaultEvent contains the ChannelEvent from the onChannelFault event.
*/
private function onProducerMessageFault(event:MessageFaultEvent) : void
{
this.addLogMessage("onProducerMessageFault(" + event.toString() + ")");
this.makeButtonRed(this.connectProducerButton);
}
/**
* Creates the Channel.
*/
private function createChannelSet() : void
{
this.addLogMessage("createChannelSet()");
cs = new ChannelSet();
channel = new WeborbMessagingChannel("WebOrbMessagingChannel", URI);
channel.addEventListener(MessageEvent.MESSAGE, onChannelMessage);
channel.addEventListener(ChannelEvent.CONNECT, onChannelConnect);
channel.addEventListener(ChannelEvent.DISCONNECT, onChannelDisconnect);
channel.addEventListener(ChannelFaultEvent.FAULT, onChannelFault);
cs.addChannel(channel);
}
/**
* Pinging WebORB
*/
private function pingWeborb() : void
{
this.addLogMessage("Pinging WebORB");
var ro:RemoteObject = new RemoteObject(REMOTEDESTINATION);
ro.source = MANAGEMENTSERVICE;
ro.endpoint = ENDPOINT;
ro.ping.addEventListener(ResultEvent.RESULT, onWebOrbPingResult);
ro.ping.addEventListener(FaultEvent.FAULT, onWebOrbPingFault);
ro.ping();
}
/**
* Initializing connection to receive unique ClientId
*/
private function initConnection() : void
{
this.addLogMessage("InitConnection");
var uri:String = URI;
wOrb_nc = new NetConnection();
wOrb_nc.client = this;
wOrb_nc.objectEncoding = ObjectEncoding.AMF3;
wOrb_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
wOrb_nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
wOrb_nc.connect( uri, "NetConnection");
}
/**
* Disconnecting the InitConnection. After this, other clients will be notified that this
* application disconnected. However, the Consumer and Producer will continue to work after
* this. This is not good behaviour. If NetConnection is disconnected, then the Consumer and Producer
* should be disconnected as well so that no messages can be delivered or gotten.
* Some thinking needs to be done concerning this...
*/
private function disconnectInitConnection() : void
{
this.addLogMessage("disconnectInitConnection()");
wOrb_nc.close();
}
/**
* Connecting as a Consumer
*/
private function connectAsConsumer() : void
{
this.addLogMessage("connectAsConsumer()");
consumer = new WeborbConsumer();
consumer.channelSet = cs;
consumer.destination = MESSAGINGDESTINATION;
consumer.subqueue = this.subQueueu.text;
consumer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onConsumerMessageAck);
consumer.addEventListener(MessageFaultEvent.FAULT, onConsumerMessageFault);
consumer.subscribe(this.clientId);
}
/**
* Disconnecting the client. Actually, the channel is disconnected.
*/
private function disconnectConsumer() : void
{
this.addLogMessage("disconnectConsumer()");
this.consumer.disconnect();
}
/**
* Creating the Producer
*/
private function connectAsProducer() : void
{
this.addLogMessage("connectAsProducer()");
producer = new WeborbProducer();
producer.channelSet = cs;
producer.destination = MESSAGINGDESTINATION;
producer.subqueue = this.subQueueu.text;
producer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onProducerMessageAck);
producer.addEventListener(MessageFaultEvent.FAULT, onProducerMessageFault);
producer.producerId = this.clientId;
producer.send(new AsyncMessage());
}
/**
* Disconnects the producer.
* This doesn't actually do anything (channel doesn't seem to be disconnected).
*/
private function disconnectProducer() : void
{
this.addLogMessage("disconnectProducer()");
this.producer.disconnect();
}
/**
* Adds a log message to the output panel.
*/
private function addLogMessage(message:String) : void
{
this.outputPanel.text += message + "\n";
}
/**
* Sets the background of a button green.
*/
private function makeButtonGreen(button:Button) : void
{
button.setStyle("fillColors", [0x40DE1C, 0x40DE1C]);
}
/**
* Sets the background of a button red.
*/
private function makeButtonRed(button:Button) : void
{
button.setStyle("fillColors", [0xFF0000, 0xFF0000]);
}
/**
* Function called by the server to give this client a unique clientId.
* This id is the id of the NetConnection (Consumer and Producer also get a Id,
* but they are not used as the unique id.
*/
public function setClientID( myID:String) : void
{
this.addLogMessage("SERVER CALL: setClientID(" + myID + ")");
this.clientId = myID;
}
/**
* Function called by server when a client has disconnected.
* As a result, all locked apples, potatoes or bananas that were locked by this client
* need to be unlocked.
*/
public function setClientDisconnected( clientID:String ) : void
{
this.addLogMessage("SERVER CALL: setClientDisconnected(" + clientID + ")");
}
/**
* Function called by server to initialize already locked apples when connecting
*/
public function initLockedAppleMessages(lockedAppleMessages:Array) : void
{
this.addLogMessage("SERVER CALL: initLockedAppleMessages(" + lockedAppleMessages.length + ")");
}
/**
* Function called by server to initialize already locked bananas when connecting
*/
public function initLockedBananaMessages(lockedBananaMessages:Array) : void
{
this.addLogMessage("SERVER CALL: initLockedBananaMessages(" + lockedBananaMessages.length + ")");
}
/**
* Function called by server to initialize already locked potatoes when connecting
*/
public function initLockedPotatoeMessages(lockedPotatoeMessages:Array) : void
{
this.addLogMessage("SERVER CALL: initLockedPotatoeMessages(" + lockedPotatoeMessages.length + ")");
}
/**
* Send a locked potatoe message
*/
private function sendLockedPotatoeMessage() : void
{
this.addLogMessage("sendLockedPotatoeMessage()");
var lockedPotatoeMessage:LockedPotatoeMessage = new LockedPotatoeMessage();
lockedPotatoeMessage.potatoeId = Math.round(Math.random() * 10000);
lockedPotatoeMessage.clientId = this.clientId;
lockedPotatoeMessage.locked = true;
lockedPotatoeMessage.userId = 1;
producer.send(new AsyncMessage(lockedPotatoeMessage));
}
/**
* Send a locked apple message
*/
private function sendLockedAppleMessage() : void
{
this.addLogMessage("sendLockedAppleMessage()");
var lockedAppleMessage:LockedAppleMessage = new LockedAppleMessage();
lockedAppleMessage.appleId = Math.round(Math.random() * 10000);
lockedAppleMessage.clientId = this.clientId;
lockedAppleMessage.locked = true;
lockedAppleMessage.userId = 1;
producer.send(new AsyncMessage(lockedAppleMessage));
}
/**
* Send a locked banana message
*/
private function sendLockedBananaMessage() : void
{
this.addLogMessage("sendLockedBananaMessage()");
var lockedBananaMessage:LockedBananaMessage = new LockedBananaMessage();
lockedBananaMessage.bananaId = Math.round(Math.random() * 10000);
lockedBananaMessage.clientId = this.clientId;
lockedBananaMessage.locked = true;
lockedBananaMessage.userId = 1;
producer.send(new AsyncMessage(lockedBananaMessage));
}
/**
* Send three messages
*/
private function sendApplePotatoeBananaMessage() : void
{
this.addLogMessage("sendApplePotatoeBananaMessage()");
sendLockedPotatoeMessage();
sendLockedBananaMessage();
sendLockedAppleMessage();
}
]]>
</mx:Script>
<mx:HBox width="100%">
<mx:VBox height="100%" width="50%">
<mx:Form width="100%" height="100%" borderStyle="solid">
<mx:FormHeading label="MSMQ with WebORB"/>
<mx:FormItem label="Id Client (provided by NetConnection)">
<mx:Label id="clientIdLabel" text="{this.clientId}"/>
</mx:FormItem>
<mx:FormItem label="SubQueue">
<mx:TextInput id="subQueueu" text="JohleroQueue"/>
</mx:FormItem>
<mx:FormItem label="Connecting">
<mx:Button
id="pingWebOrbButton"
label="Pinging WebORB to ensure MessagingServer is started"
click="{pingWeborb()}"
width="100%"
/>
<mx:Button
id="initConnectionButton"
label="Initializing connection to get unique ClientId"
click="{initConnection()}"
enabled="true"
width="100%"
/>
<mx:HBox width="100%">
<mx:VBox
height="100%"
horizontalAlign="left"
borderStyle="solid" borderThickness="3" borderColor="#000000"
paddingLeft="10" paddingBottom="10" paddingRight="10" paddingTop="10"
>
<mx:Button id="connectConsumerButton"
label="Connect as Consumer to receive the messages"
click="{connectAsConsumer()}"
enabled="true"
/>
<mx:Button id="connectProducerButton"
label="Connect as Producer to send the messages"
click="{connectAsProducer()}"
enabled="true"
/>
</mx:VBox>
<mx:VBox id="channelVBox"
height="100%"
cornerRadius="3" borderStyle="solid" borderThickness="3" borderColor="#000000"
paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"
horizontalAlign="center" verticalAlign="middle"
>
<mx:Label text="Channel" fontSize="20"/>
</mx:VBox>
</mx:HBox>
</mx:FormItem>
<mx:FormItem label="Disconnecting">
<mx:Button id="disconnectingNetConnectionButton"
label="Disconnecting NetConnection"
click="{disconnectInitConnection()}"
enabled="true"
/>
<mx:Button id="disconnectingConsumerButton"
label="Disconnecting Consumer"
width="100%"
click="{disconnectConsumer()}"
/>
<mx:Button id="disconnectingProducerButton"
label="Disconnecting Producer"
width="100%"
click="{disconnectProducer()}"
/>
</mx:FormItem>
</mx:Form>
</mx:VBox>
<mx:VBox width="50%">
<mx:Form borderStyle="solid" width="100%">
<mx:FormHeading label="Bindings to connected properties"/>
<mx:FormItem label="NetConnection connected">
<mx:CheckBox id="netConnectionCheckBox" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Channel connected">
<mx:CheckBox selected="{this.channel.connected}" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="ChannelSet connected">
<mx:CheckBox selected="{this.cs.connected}" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Consumer connected">
<mx:CheckBox selected="{this.consumer.connected}" enabled="false"/>
</mx:FormItem>
<mx:FormItem label="Producer connected">
<mx:CheckBox selected="{this.producer.connected}" enabled="false"/>
</mx:FormItem>
</mx:Form>
<mx:Form borderStyle="solid" width="100%">
<mx:FormHeading label="Sending messages"/>
<mx:FormItem>
<mx:Button id="sendLockedAppleMessageButton"
label="Sending a Locked Apple Message"
click="{sendLockedAppleMessage()}"
enabled="true"
width="100%"
/>
<mx:Button id="sendLockedBananaMessageButton"
label="Sending a Locked Banana Message"
click="{sendLockedBananaMessage()}"
enabled="true"
width="100%"
/>
<mx:Button id="sendLockedPotatoeMessageButton"
label="Sending a Locked Potatoe Message"
click="{sendLockedPotatoeMessage()}"
enabled="true"
width="100%"
/>
<mx:Button id="sendLockedAppleBananaPotatoeMessageButton"
label="Sending a Locked Apple and Banana and Potatoe Message"
click="{sendApplePotatoeBananaMessage()}"
enabled="true"
/>
</mx:FormItem>
</mx:Form>
</mx:VBox>
</mx:HBox>
<mx:HBox width="100%" height="100%">
<mx:FormItem label="Output Panel" width="100%" height="100%" borderStyle="solid">
<mx:TextArea width="100%" height="100%" id="outputPanel"/>
</mx:FormItem>
</mx:HBox>
<mx:HRule width="100%"/>
<mx:HBox verticalAlign="middle">
<mx:Label text="Created by Johlero (Lieven Cardoen) RDB Technologies"/>
<mx:LinkButton label="Johlero Blog Link" click="navigateToURL(new URLRequest('http://blog.johlero.eu'), '_blank')" textDecoration="underline" color="#0D005A"/>
</mx:HBox>
</mx:Application>