Defending Flex

Posted by admin on August 3rd, 2008

In my Company we develop educational software. Authors can create content in a backoffice and present them to students in different kinds of contexts.

The first and second version use the same backoffice created mainly in ASP. In spite of the fact that usability isn’t that good, it is still being used by our customers. The frontend for the first version was written in flash using Actionscript 1, the second version used Actionscript 2. In AS1 we had an swf for each type of exercise, in AS2 we had one big swf.

For the third version we decided to use Flex for backend and frontend. There have been hours of discussion about this decision in our company and even customers tend to argue about using Flex. This post is about this discussion, about why we made that choice and the consequences of this choice.

First let me state some of the requirements.

  • Customers ask for interactive exercises having dragndrop, video, audio, images, connecting things, …
  • An author need an easy tool to create these exercises and preview them.
  • Scenarios can be created that generate all sorts of tests and these tests can be previewed.
  • An intelligent player can present these tests to frontend users.
  • The application may need to run offline in the future (frontend and backend)
  • CD-roms must be made with the content

For the frontend we didn’t have a lot of options two years ago. Silverlight wasn’t even born yet (or maybe just), haven’t read a lot of good things about Java FX although I haven’t tested it myself, Javascript and AJAX do not seem suited for this kind of applicatoin… So Flash seemed the best choice and as of today this is still the best choice. Having an application running in the browser is a big advantage for these kind of applications. The application is loaded once into the browser which increases usability a lot, the different parts of the application can talk easily with each other, communication with the server is easy with remoting technology like WebORB or FluorineFX and interactivity like Drag and Drop, audio, video, … is a pleasure to develop, you don’t need to worry about different browsers, Linux, Mac and Windows supported and creating CD-roms is quite easy with tools like ZINC of Adobe Air. The downside is that all logic lives on the client side. First of all this means that reverse engineering the swf is not hard at all for someone who knows how to do it, even if the swf is encrypted, security needs to get more attention, programming an application is harder than programming pages so you need experienced developers, the Flash Player Plugin needs to be installed (in big companies this is often a big problem because users of a computer do not have rights to install a new plugin. The admin of the company needs to do this and often these admins are not eager to do this…) and few graphical designers have experience with Flex.

Creating the backend with .NET technology would probably be twice as fast. You can easily seperate work without affecting other parts of the project (with an application changing something often affects other parts of the application), there are a lot of .NET developers an few Flex developers, doing it in Flex still needs a server layer (WebORB with Services and some logic),… So why did we choose Flex to create our backend? Well, there are a few arguments that are important enough for this decision:

  1. A lot of logic from the player can be reused in the backend, like serializers, deserialers, our framework, …
  2. Creating interactive exercises with Flash is a hundred times easer than doing it with Javascript.
  3. Showing a preview of the exercise can be done without having to show a popup loading an swf to show the exercise. (as we had to do in our first version).
  4. Bringing it offline to Mac, Linux and Windows is a piece of cake with Adobe Air. If you would develop the backend in .NET, bringing it offline to Windows would be possible, but bringing it to Mac and Linux wouldn’t. (Even with Silverlight you would be doing the same as in Flex+ no Linux with Silverlight and not as mature yet as Flex).

It’s true that some parts like reports, access and rights management, creating scenarios, … would be a lot easier with .NET but then you would be mixing technolgy and that wouldn’t look all that nice now would it?

It’s not easy to defend such choices. For small projects backends are usually made with .NET and frontends with Flash if interactivity is needed. As a project like ours gets very big, you need to be thinking about maintenance, design patterns, different customers, budget, resources, … and then Flex doesn’t allways appear ideal… Ok, there’s no problem with different browsers, you have an application feeling in the browser, it’s  supported on Mac, Linux, Windows, but is it worth it? I find it allready difficult to explain the decision on my blog here to developers, imagine explaining it to a customer… Switching to product development in our case would be the best move according to me. The bigger a project comes, the more time it takes to add functionality. And then there’s this worry of me about how big an swf can get before having problems? Our swf is currently about 1meg big. The backend also loads a lot of stuff from the server into the memory (clientside)… Are there limitations?

I have played a little bit with silverlight in the last days and it looks promising. If it would ever get as mature as Flex, then I would certainly switch. A tool like Visual Studio is a treat to work with and having all the logic in one technology would be great. Now we have to port a lot of logic from Flex to .NET to create reports (for instance in Reporting Services), to have exports to paper from tests, …

I do not intend to start a discussion about which technology is better. For me there are customers, budget and demands and trying to meet those demands. All technologies will have their advantages and disadvantages and it’s up to the team to choose the right technology to do the job.

To the future!

Ciao!

Flex integration with Microsoft Message Queuing (MSMQ) using WebORB – Part I – Client Side

Posted by admin on May 31st, 2008

A big problem in my current project is Concurrency. A client loads a Tree in his Flex application and starts making changes to this tree. If another client also makes changes in the Tree, then we have a Concurrency problem. We thought of two approaches of dealing with this problem. One of them is using Messaging with MSMQ. We did however had some issues developing this and are still trying to make it work.

We mainly worked with two examples provided by WebORB to figure things out. One of them is the Flex Messaging and MSMQ  example from the WebORBConsole –> Examples –> Real-time Messaging. The other one is the MSMQ to Flex Data Push example from the site of the midnight coders. In the first example Flex is the Producer and Consumer of Messages. In the second example the Server produces Messages and Flex consumes them.

What do you need to run these examples:

  1. MSMQ: If you look into Computer Management under Services and Applications you should see a folder Message Queuing. If not I suggest you google to find out how to install this onto your computer. For Vista you’ll need to go to the Control Panel –> Programs and Features –> Turn windows features on or off. There you should find a checkbox for installing MSMQ.
  2. WebOrb for .NET  –> In your site you only need the weborb.dll, so this installation isn’t really needed. But it comes with a lot of documentation and examples, so if you haven’t installed it yet, go and do so now!
  3. The Messaging Server (WebOrb) should be online. If you’re using the WebOrb30 installation to run your examples, then the Messaging Server is started by weborbee.exe. In your project website however, you shouldn’t use this weborbee.exe. You only need to copy the global.asax. If you look into this global.asax, you’ll see the weborbMessagingServer is started there. I’ll show in the examples how to make sure the MessaginServer is online.

 When you open the Flex Consumer Resource from the second example you’ll see in the properties of the Project –> Flex Compiler that a services-config.xml file is compiles with the application. In this file Channels and Destinations are declared. We left this out so we could choose at runtime which Channel and Destination to use.

Ok, let’s start with the Flex Client Side. Here’s the example somehow adjusted to our means. I’ll go through it piece by piece. For now don’t bother too much about the server side. I’ll go deeper into that later.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
public function onCreationComplete(event:FlexEvent):void {
registerClassAlias("Messaging.Car", Car);
pingWeborb();
}
 
private function pingWeborb():void {
var ro:RemoteObject = new RemoteObject("GenericDestination");
ro.source = "Weborb.Management.ManagementService";
ro.endpoint = "http://{server.name}/indiegroup-edumatic3-prod/weborb.aspx";
ro.ping.addEventListener(ResultEvent.RESULT, onPingResult);
ro.ping.addEventListener(FaultEvent.FAULT, onPingFault);
ro.ping();
}

We register an Alias for the Car class so it’ll be mapped correctly to the C# Messaging.Car class.
Next we call the function pingWeborb() which will ensure us that the MessagingServer is started before we start to send Messages. By triggering the weborb gateway (weborb.aspx) in your site, you’ll be starting the MessagingServer (in Global.asax). If you are not using the weborb30 site, make sure you haven’t started the MessagingServer with the Weborbconsole in weborb30 site. If you want to be sure of this, go to Task Manager –> Processes and kill the w3wp.exe process.

The GenericDestination can be found in the remoting-config.xml in the WEB-INF\flex folder along the server side. More on this later. The source is the Class instance that will be created and the endpoint the url of the gateway. Make sure you use the RemoteObject class from the mx.rpc.remoting.mxml package, as this RemoteObject has an endpoint property. There’s also a RemoteObject class in the mx.rpc.remoting package which has no endpoint property. Adding two EventListeners and executing the ping() function in the Weborb.Management.ManagementService class instance.

1
2
3
4
5
6
7
8
private function onPingResult(result:ResultEvent):void {
connectAsConsumer("johleroqueue");
connectAsProducer("johleroqueue");
}
 
private function onPingFault(fault:FaultEvent):void {
Alert.show( "Server reported an error - " + fault.fault.faultDetail);
}

 If the Ping was successfull, then onPingResult should be triggered, in which we’ll connect as a Consumer and as a Producer. If the Ping was unsuccessfull, onPingFault will be triggerd and an Alert Box will be shown with the error. If something goes wrong here, I would start a http sniffer like Charles to see if the Gateway is called. If it is, start by creating some breakpoints in Flex and certainly in the global.asax on the serverside. Make sure to keep on reading even if things don’t work as I will talk about some other problems I’ve encountered. Maybe that one of these problems will be the issue that’s causing your problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private function connectAsConsumer(subTopic:String):void{
var cs:ChannelSet = new ChannelSet();
var uri:String = "rtmp://{server.name}:2037/MessagingService";
var channel:WeborbMessagingChannel = new WeborbMessagingChannel(subTopic, uri);
channel.addEventListener(MessageEvent.MESSAGE, onMessage);
cs.addChannel(channel);
 
consumer = new WeborbConsumer();
consumer.channelSet = cs;
consumer.destination = "ExampleDestination";
consumer.subqueue = subTopic;
consumer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onMessageAck);
consumer.addEventListener(MessageFaultEvent.FAULT, onMessageFault);
consumer.subscribe();
}

Ok, first we connect as a Consumer, because the connectAsProducer function will also be sending a message. First we create a ChannelSet containing a WeborbMessagingChannel. I haven’t gone deep into this Channel thing, but one thing that was strange to me was that no site is given in the rtmp uri. Apparently the MessagingServer is listening to a port. The /MessagingService points to a folder in the Applications folder under the root of your site. In this MessagingService folder it’s possible to place an app.config where you can change some configurations. The channel triggers a MessageEvent.MESSAGE event when a message is Consumed.

The destination can be found in the messaging-config.xml under WEB-INF\flex. In there you’ll find an entry path with the name of the queue. This path together with the subqueue (in my case johleroqueue) will be the name of your queue. If the path is .\private$\WEBORB-[destinationName] and the destination name “ExampleDestination” then a queue weborb-exampledestination-johleroqueue will be created. The first time the queue is used it will automatically be created by weborb. However, if weborb creates the queue, you will not be able to access it with the Computer Management tool. Apparently access is denied. A workaround for this is to manually create this queue before running the example. If you manually create it, you’ll have access rights. However, you’ll need to give the Network Service rights to the queue, otherwise the messages will not arrive (you can check this!). Weborb will then use the queue you created if you use the same name off course. The ACKNOWLEDGE event listener will let the consumer know if subscription was successfull. The other listeners are clear enough I guess.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private function connectAsProducer(subTopic:String):void{
var cs:ChannelSet = new ChannelSet();
var uri:String = "rtmp://{server.name}:2037/MessagingService";
var channel:WeborbMessagingChannel = new WeborbMessagingChannel(subTopic, uri);
cs.addChannel(channel);
 
producer = new WeborbProducer();
producer.channelSet = cs;
producer.destination = "ExampleDestination";
producer.subqueue = subTopic;
producer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onMessageAck);
producer.addEventListener(MessageFaultEvent.FAULT, onMessageFault);
 
var car:Car = new Car();
car.Make = "Zakke";
car.Mileage = 10;
car.Model = "Makke";
producer.send(new AsyncMessage(car));
}

Connecting as Producer is quite similar to the Consumer with the exception of the send function. Meanless to say that the Producer and Consumer need to connect to the same queue. Next the Producers sends a Car instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
private function onMessage(event:MessageEvent):void {
trace(event.message.body);
//Put a breakpoint here
//var body:* = event.message.body;
}
 
private function onMessageAck(event:MessageAckEvent):void {
//Put a breakpoint here
}
 
private function onMessageFault(event:MessageFaultEvent):void {
//Put a breakpoint here
}

If the Consumer has successfully suscribed, then a onMessageAck should be triggered. If the Producer has successfully connected, then onMessageAck should be triggered a second time. The onMessageAck from the Producer does not mean that the message has successfully been send, it only means that the Producer has been able to connect to the MessagingService. There doesn’t seem to be a clear way of knowing if the Message has successfully been send. However, if the Consumer gets the message, then other Consumers will have gotten the message too. After this onMessage should be triggered and a Car (if the server side is configured right) should be delivered.

 

Adios, Johlero!

Thx to the midnight coders!

Patterns of Enterprise Application Architecture

Posted by admin on May 13th, 2008

I’ve been reading a book written by Martin Fowler on Patterns of Enterprise Application Architecture. It’s a very interesting book and I’m now contemplating on organizing the domain logic in layers and mapping it to relational databases. I find it a very hard matter how to make a bridge between a relational database working with foreign keys and a Object Model working with references to other objects. In the beginning of our big project we made a decision to have the domain logic on the client side in a flex application. On the server side we have a tool ‘SubSonic’ that does a lot of work for us, but not enough. The client expects certain Data Transfer objects from the server that are more complex than the tables in the database. This means that working with a Row Data Gateway of Table Data Gateway and sending those instances to Flex is not an option. Sometimes objects are complex and have collections of other objects. So we need Data Mappers to map SubSonic instances to DTO instances. And now we have even ported some of the Domain Logic to the server because we need to create reports and this can only be done on server side due to performance issues. So now we have a SubSonic Model, a DTO Model and the Domain Logic… In my opinion this is too much… I will try to have a look at LINQ but I’m not sure that this will make things easier. Also, changing something to the domain logic needs to be done now in two places… In AS3 (Flex) and in C# (.NET)… But if we have the domain logic also on the servers side, it can be a big advantage in the future (SilverLight, Reporting Services, …).

I am now looking at Identity Maps and I’m wondering if I’ll need an identity map for DTO’s and for Domain Logic… I thing I’ll just go for now with Identity Maps for the DTO’s. There’s a big difference between a Client running in a single thread and a server running different threads for different client requests. I’m hoping to be able to cache things on the server side using Unit of Work patterns.

Ciao! Johlero!

pixel Patterns of Enterprise Application Architecture

Copyright © 2007 Lieven Cardoen. All rights reserved.