WebORB licensing restrictions removed

30 09 2008

Until very recently, the Flash remoting solution, WebORB, was limited in that it couldn’t be used in a Software as a Service (SaaS) instance without a valid support plan. That meant a yearly fee of a few thousand USD.

However, I have been informed today that this restriction has been removed.

Having read it myself, I can confirm that WebORB license now allows the solution to be used in software applications that earn themselves an income.

From the license itself: (please follow the link above for the actual wording)

“… and does not prevent developers from using and bundling Software with higher level applications that run on these platforms….”





Flex, .NET 3.5 with LINQ to SQL part 2 (synchronising from Flex to LINQ)

29 09 2008

March 2009: This post is outdated, please see the latest article on FLEX & LINQ:

http://justinjmoses.wordpress.com/2009/03/19/rich-clients-flex-air-silverlight-linq-data-across-the-pipe/

 

Right.

So, getting your objects from your .NET 3.5 Linq to SQL setup to Flex is fairly easy. Getting the changed data back and synchronised to your DB is a different story.

The great thing about LINQ is that the data you retrieve and modify in .NET will automatically sync back to the DB by calling the SubmitChanges() method on your context (Linq to SQL) object.

The problem is of course when this data comes back in from Flex, the system doesn’t know what exactly has changed.

Now, the first thing to realise is that your Value Objects in Flex should NOT have the foreign key IDs in them. Why? Because say in the Company/Employee example, if you submit a Company object back to the system, with each Employee in the list having both a CompanyID AND a Company object reference, how will the LINQ system know which is the correct reference?

These foreign IDs will try to get serialised on the remoting level and be ignored. Good. We’re dealing with object references now, and foreign key ids are useless. If I want the foreign key of some employee, I would say: EmployeeObj.Company.CompanyID

Now, in .NET, I have a “Save()” method that I want to essentially insert/update the object and all objects within in.

Using the example before, say I have a company object, and that has a list of Employees. Then if I have a Save(Company c) method, I want the company object to insert/update, and the list of employees to automatically synchronise.

You can try deleting the old object and then inserting the new

So,

SaveCompany(Company newCompany)
{

DataClassesDataContext db = new DataClassesDataContext();
if (newCompany.CompanyID > 0)
{

Company oldCompany = db.Companies.Single<Company>(c => c.CompanyID = newCompany.CompanyID);
db.Companies.DeleteOnSubmit(oldCompany);
}
db.Companies.InsertOnSubmit(newCompany);
db.SubmitChanges();
}

This will nicely handle an insert/update of the company object, but it won’t deal with your Employee objects that well. Especially when each Employee references anthor table that essentially depicts there type./

Say each Employee has a foreign key reference to EmployeeType. Employee type is a static naming table that has a set of 5 records: “Manager”, “Sales Coordinator”, “Receptionist”, “Consultant” and “Helpdesk”. Then my Employee object will have an EmployeeType property (loaded via LINQ). Now, when this goes through LINQ, I believe during the serialisation, the creation of a “new” object EmployeeType will mean that the code above will create a new EmployeeType record for the Employee. Ouch.

So even though you may have sent all the employees through LINQ to Flex via a Company object, when it comes back, even if unchanged, all these employees will have references to new EmployeeType objects.

The way to solve this is fairly easy:

foreach (Employee e in newCompany.Employees)
{
   EmployeeType type = db.EmployeeType.Single<EmployeeType>(t => t.TypeID == e.EmployeeType.TypeID);
   e.EmployeeType = type;
}

oldCompany.Employees = newCompany.Employees;

Unfortunately, it’s not an easy process to learn how exactly to handle each scenario in synching LINQ and Flex, but one thing’s for sure, it certainly makes code lighter, and a lot easier to update.





Flex, .NET 3.5 with LINQ to SQL

23 09 2008

March 2009: For more information see the latest article on FLEX & LINQ:

http://justinjmoses.wordpress.com/2009/03/19/rich-clients-flex-air-silverlight-linq-data-across-the-pipe/

——————————————————————————-

I had certainly delayed looking at LINQ for too long.

After seeing a screencast on some of the new features in ASP.NET I noticed the very handy LINQ to SQL item.

Well.

Let’s just say I’m not using strongly typed datasets anymore.

LINQ provides strongly typed access to your database (tables, views, sprocs and function) while also allowing you to query those results.

Whilst many still advocate the use of stored procs for larger and more advanced or intensive queries, at least some of the simple overhead can be reduced. Furthermore, updating your C# classes to reflect your DB is as simple as updating the LINQ to SQL item.

But the major advantage from a Flex remoting perspective is how easy it is to have all this returned data in your client.

Say I have three tables: (already linked with relationships via foreign keys)

Employee, Company & Position

I add the LINQ to SQL item to my solution. Inside, I connect the LINQ object up to the db and drag in my database objects. Voila, I have the strongly typed classes: “Employee”, “Company” and “Position”. None of this DataRow, DataTable, DataAdapter business.

Using LINQ syntax, I can do simple queries on the spot, like:

DataClassesDataContext db = new DataClassesDataContext();

var data = from e in db.Employees where e.CompanyID == someCompanyID select p;

List<Employee> employees = data.ToList<Employee>();

Now, I can return this list to either FluorineFx or WebORB and the ArrayCollection that the List is serialised into will contain an array of Employee Value Objects (my Employee.as file). Nothing special there.

BUT, the “Company” property is also provided. This is the Company property that is automatically generated in LINQ to SQL that provides the foreign key reference to the company.

This holds for all your foreign keys.

So if you want to reduce your overhead from a C# (writing classes for your db objects) and DB perspective (writing sprocs for every data call), then take a gander at .NET 3.5.

NOTE:

  • If you weren’t aware, .NET 3.5 framework is actually an addition to .NET 2.0. This means that once you install the framework on a machine, no manual IIS settings are required (as opposed to the 1.1 to 2.0 switch) to activate 3.5 on a website or virtual directory.
  • Both FluorineFx and WebORB support .NET 3.5




Flex 3 : IE 6 : SSL and mixed secure items

9 09 2008

Bleh.

This wasn’t a fun one to try to debug.

Essentially, I moved a flex project over to SSL. This meant a simple header redirect on all requests and using the Secure AMF channel for remoting. No problems.

But wait, IE 6 starts throwing me “This page contains both secure and nonsecure items. Do you want to display the nonsecure items?”

This will be familiar to many people, and it would probably be acceptable if it didn’t keep reloading the page no matter which button I pressed.

One word – WTF? I checked EVERY link and reference and everything was relative and thus HTTPS. FireFox reported that everything was hunky dory, even the favicon, so WTF?

Turns out IE6 doesn’t like iFrame tags without a SRC attribute. Fine. But so what? I’m not using iFrames without SRC tags. Hangabout, checking history.js which is deployed alongside any Flex app, you’ll notice around line 381:

var _initialize = function () {
if (browser.ie)
{
var scripts = document.getElementsByTagName('script');
for (var i = 0, s; s = scripts[i]; i++) {
if (s.src.indexOf("history.js") > -1) {
var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
}
}
historyFrameSourcePrefix = iframe_location + "?";
var src = historyFrameSourcePrefix;
var iframe = document.createElement("iframe");
iframe.id = 'ie_historyFrame';
iframe.name = 'ie_historyFrame';
//iframe.src = historyFrameSourcePrefix;
try {
document.body.appendChild(iframe);
} catch(e) {
setTimeout(function() {
document.body.appendChild(iframe);
}, 0);
}
}

SOLUTION:

Notice the commented line? Strange. I’m not sure why it’s been commented by Adobe, but this is our problem right here. This iframe is causing IE6 to have a cry under SSL.

I’ve uncommented it and since I’m using BrowserManagement instead of HistoryManagement, have found that everything is worked as expected. I’m too tired to go looking to see what minute repercussions there may be, but if anyone has anything to add, please be my guest.





Getting started with Flex 3 and Flash Media Server 3

4 09 2008

This is a just a brief get up and go starting off with Flash Media Server 3 and Flex 3.

For the purposes of this discussion, I’ll be using Flash Media Development Server 3.

The goal of this post is to have two videos streamed into a Flex app – one a live stream, the other a recorded stream.

What you’ll need:

  1. Flash Media Development Server 3 …. free download
  2. Flash Media Encoder 2.5 … free download
  3. a web cam & a mic

So to start off, you download and install the Flash Media Development Server 3 software.

Once installed, jump into the Flash Media Administration Console to have a look around. Guess what – there’s not much to see yet.

Now install the Flash Media Encoder software.

This will take the streams coming in from your webcam and mic and convert them to video. Whilst it’s running – you have a live stream running in “rtmp://localhost/live/livestream” and if you stop it running, it will save a FLV file in the “My Videos” folder of your user.

So do a short 20s video and stop the encoder. You should have a small FLV sitting in “My Videos” called “sample.flv”. This you can copy to your video-on-demand’s media folder which is under “applications/vod/media”.

Now, start the encoder again but leave it on to generate a live stream.

In Flex, write a small app that has two VideoDisplay controls – one for your live stream and one for the video on demand.

<mx:VideoDisplay source=”rtmp://localhost/live/livestream” live=”true” autoPlay=”true” />

<mx:VideoDisplay source=”rtmp://localhost/vod/sample.flv” autoPlay=”true” />

When you run the app, you’ll see your stream and your video, running side by side.





FluorineFx and WebORB coding differences part1

3 09 2008

I thought I’d compile a list of differences between coding an Flex .NET remoting solution in FluorineFx and WebORB.

First off, the versioning:

FluorineFx: 1.0.0.13

WebORB (.NET): 3.5

Now, for various features/actions. These are typically in no order:

1. Registering a DLL to work in remoting

both: deploy the DLL in the “bin” folder (alongside “FluorineFx.dll” and “weborb.dll” respectively)

2. Destinations/Channels (in the WEB-INF/flex folder)

WebORB: Uses a “GenericDestination” that is exposed to all classes in all DLLs alongside the

<destination id="GenericDestination">
<properties>
<source>*</source>
</properties>
</destination>

Uses a set of channels including the default AMF channel

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint uri="weborb.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>false</polling-enabled>
</properties>
</channel-definition>

FluorineFx: Uses the “fluorine” destination that is open to all classes exposed as remoting (see point 3 below).

<destination id="fluorine">
<properties>
<source>*</source>
</properties>
</destination>

Uses a set of channels including the default AMF channel

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://{server.name}:{server.port}/{context.root}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
</properties>
</channel-definition>

NOTE: Due to a bug in Flex Builder 2 & 3, you must “Clean” your project to register and changes in the WEB-INF xml files.

NOTE: You can see that the “ContextRoot” setting is important in FluorineFx. If you aren’t running off the root domain, but in some other folder / virtual directory, you need to set up the Context Root to match that folder structure. ie. If you’re testing in “http://localhost/TestFolder&#8221; then you must set your Context Root in Flex Builder (Project Properties) to be “TestFolder”.

3. Exposing classses/methods from a DLL to Flex.

WebORB: WebORB will expose all namespaces/classes/methods from a destination by default.

This destination, when combined with the “source” property on a remote object, will expose everything inside your DLLs to the web. This can be toggled in the weborb.config file (under security->deploymentMode) to “closed”.

FluorineFx: Only those classes compiled with the [RemotingService] Attribute in C# will be exposed via FluorineFx, and even then only their public methods. NOTE: that class must be using the “FluorineFx” namespace.

4. Using SSL remoting

WebORB: The SSL channel is there by default “my-secure-amf”. If you ran your app from HTTPS, it would work by default as both the normal and the HTTPS channels are defaults. Alternatively (and for best practises), you can set up a destination to use it:

<destination id="MyDestination">
<channels>
<channel ref="my-secure-amf" />
</channels>
<properties>
<source>My.Name.Space.MyServiceClass</source>
</properties>
</destination>

FluorineFx: Doesn’t come bundled with a secure channel, but can do it easily. You just need to add the following to your services-config.xml file

<channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
<endpoint uri="https://{server.name}:{server.port}/{context.root}/Gateway.aspx" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
</channel-definition>

Then you can add a destination in remoting-config.xml that uses “my-secure-amf” (see the WebORB solution above).

5. Manage security

WebORB: The WebORB console is fully featured to allow you to setup which services can be exposed to which users. You can limit a namespace, class or method by role, hostname, ip range or single ip (allowing masks). Essentially this just adds security configuration data to weborb.config but it’s handy.

To implement custom authentication and authorisation, you must implement Weborb.Security.IAuthenticationHandler and Weborb.Security.IAuthorizationHandler respectively (and add a reference to this classes in your weborb.config file under the security setting). Then you should be able to use the setCredentials() method on your remote object.

FluorineFx: Uses a similar approach to security, but it’s all done in the remoting-config.xml file instead. You need to manually add the constraints and apply them to destinations.

<destination id="MyService">
    <channels>
      <channel ref="my-amf" />
    </channels>
    <properties>
      <source>My.Name.Space.MyServiceClass</source>
    </properties>
    <security>
      <security-constraint ref="privileged-users"/>
    </security>   
  </destination>

and then in your services-config.xml file

  <security>
    <security-constraint>
      <auth-method>Custom</auth-method>
      <roles>
        <role>admin</role>
        <role>privilegeduser</role>
      </roles>
    </security-constraint>
    <login-command class="My.Name.Space.MyLoginCommand" server="asp.net"/>
  </security>

Like WebORB, you’ll need to define your own authenticator/authoriser. You must implement the FluorineFx.Security.ILoginCommand interface. You then insert it’s name aboce, in the “login-command” setting above.


6. Data Type Mapping

Both: use the [RemoteClass(alias="...")] metadata syntax above your Value Objects in ActionScript to ensure the remoting gateway will return your objects as the correct type.

WebORB: Returns a DataTable as an array of objects (associative arrays representing a row). Returns DataSets as an object (associated array of arrays of associated arrays). Can optionally use Attribute [ReturnType("namespace.actionscriptClassName")] before your C# method to tell WebORB how to serialise the data in the DataTable (I can’t get this to work though).

FluorineFx: Must be told directly which type of data the DataTable/DataSet will be returning. Otherwise will return DataTables and DataSets in flat array without column associations.

You’ll need to use Attributes above methods in C#: [DataTableType(string remoteClass)] & [DataSetType(string remoteClass).





Easy coding to understanding Cairngorm

2 09 2008

Update: The below post is a how-to for the legacy Cairngorm 2 framework. Cairngorm 2 relies on static singletons and as such cannot be properly unit tested. It is a legacy framework and should no longer be used for RIAs.

Please look at Adobe’s prescription for Cairngorm 3. Consider using a modern micro-architecture such as Robotlegs or Parsley.

Ok, so I’m not going to try and teach the Cairngorm micro-architecture for Flex here.  The kids at Adobe did a fine job of that.

What I am showing here is, a very simple implementation of Cairngorm. Even though I’d seriously recommend anyone starting out to look at the Cairngorm Store first, I thought I’d share my experience implementing a tiny  Cairngorm solution. The solution here is essentially paraphrasing the Cairngorm Store source.

You can download the project here.

Note: it is set to run from http://localhost/TestCairngorm (you’ll need to setup this Virtual Directory to test it locally)

The project’s goal is to show the contents of an XML file, which will be deployed alongside the application.

It illustrates the steps needed to get your project off the ground in Cairngorm:

  1. Write a bindable model that extends from ModelLocator. Remember: the Model shouldn’t know anything about either the View or the Controller.
  2. Include code to the Singleton of that model in your main application
  3. Create your value objects (this was not strictly required in the above project, but added to highlight the correct structure).
  4. Write a services file that extends the ServiceLocator and contains all the services you want to access (HTTP/Web/Remote).
  5. Add the services to your main application.
  6. Write a delegate for each type of value object you have. This is optional but seems best-practise.  The delegate will call the appropriate service via the service locator for each method it provides. It will ensure the responder (the command that calls the delegate) receives the response.
  7. Write a command for each of the various commands you have within your application. These should execute() the call to load your remote data via the delegate and handle the reception of data in result() (and likely modify your model)
  8. Write an event that corresponds to each command along with any data that will need to accompany the event (user data or what-have-you). Doesn’t have to be one event per command – you can combine events together in one class with different types.
  9. Write a controller (extending from FrontController) that adds all the commands to this Singleton when instanced (tying the events and the commands together)
  10. Add the controller to the main application.
  11. Start creating your view. Ensure that you bind your view items to your model elements, so that when the model updates, so will your view. Try not to reference your model in your view via the Singleton class name but rather pass the appropriate model data in from the main application. (This helps improve the reusability of your view, decoupling it from the model).
  12. Use the CairngormEventDispatcher to dispatch your events in the view as you see fit. This will then call the commands via the controller, which call the appropriate service, update the model if required, and will update your view.







Follow

Get every new post delivered to your Inbox.