Googolflex!!
  • Home
  • About
  • Contracting

Recent Posts

  • Sprint’s new “Simply ‘Almost’ Everything®” Plans
  • CSS Changes in Flex 4
  • Dotted Underline LinkButton (Flex)

About The Author : jwd

This is John Dusbabek's tech blog. John is a software engineer and Flex developer in Provo, UT, where he lives with his lovely wife and four sons.

Recent Comments

  • Nikos on Flex: Binding to an Interface
  • Iain Hosking on Apache mod_proxy_balancer: No Protocol handler was valid

Archive for ColdFusion Enterprise Server

Dec
22

JUICE chat (Stratus Peer to Peer)

Posted by: jwd | Comments (0)

One of my ongoing weekend projects is an AIR chat application, recently rechristened “JUICE” a.k.a. “John’s Ultimate Internet Chat Experience”. I realize that may only be the case for myself, but the project has been very educational and entertaining for me.

The initial release used AIR/Flex as the front-end, ColdFusion and MySQL for the backend, and BlazeDS messaging for message transmission and “peer discovery”.  I worked on it over a couple weeks adding features like encryption, toast-style notifications, as well as a few other less notable things.

I knew the architecture was awful and would never scale beyond a couple hundred users (if that many). Here’s the basics of how it worked:

  1. The user would login, ColdFusion/MySQL would send back a list of chat buddies.
  2. Each logged in user would ping the messaging server every 10-30 seconds to announce “I’m still here!”
  3. The pings would be broadcast to everyone logged in (and connected to the messaging server). The application would filter out the ones it was interested in based on user id.
  4. Sending messages worked similarly, the user would send the message (which included information about the intended recipient), which would then be broadcast to EVERYONE.
  5. Everyone would filter this information, and the recipient would know it was for him, and would display it.

You can see why this would not scale well, the amount of traffic and pinging going on.  Eventually even a user with only 1 or 2 buddies would notice a significant drop in performance as the number of total users increased.  There are some applications of “chat” for which BlazeDS messaging and polling is well suited for (like a chat room).  A chat application involving “buddies”  is much better suited for P2P.

Enter Stratus.  I discovered Stratus a few months ago but was unwilling to delve into it on account of my hectic schedule.  Fortunately one of my friends went and did all the dirty work figuring out how to get it up and running (turns out it’s pretty easy) and I was able to apply it to my chat client.

I’m very pleased with the results, though it’s still very much a work in progress.  I’ve even been able to add video and voice chat features, which is why I went through the trouble in the first place.  Here is how my peer discovery mechanism operates.  It requires only 3 calls to the server per client (which I could easily condense to 2 if I wanted).

  1. The user logs in.
  2. If the user successfully authenticated, he connects to Stratus and receives his peer ID.
  3. The user updates his peer ID in the database (which was set to 0) and gets a list of his buddies and their peer IDs.  I also update information like whether or not I have a camera/mic.
  4. The user processes his buddy.  If the peer ID is something other than 0, then I know this buddy logged in before me, so I must send him my peer ID.
  5. Any buddies that have a peer ID of 0 are not logged in, I need to listen for them though since they will get my peer ID when they log in.
  6. When I log out or close the application, I call the server and reset my peer ID to 0.  I also notify all of my connected peers I’m logging out.

There are a few more steps in the process, but it decreases the load on the server significantly, transferring the “burden of proof” onto the clients.

Interesting to note is the way I get the peer ID of a client who connects after me (step 4).  I don’t actually have to make a call for this, rather he simply has to start broadcasting to me on the NetStream I set up to listen for him (step 5).  When the connection is made, an event will be dispatched by the NetStream class.  In fact, 3 events will be fired, I just chose to act on one of them.

The peer ID can be obtained from the peerStreams array on the publishing NetStream.  I then use that information to set up my subscribing NetSream.

if (this.peerId == null || this.peerId == "0") {
    this.peerId = publishNetStream.peerStreams[0].farID;

    this.subscribeNetStream = new NetStream(model.netConnection, this.peerId);
    this.subscribeNetStream.client = new NetStreamClient();
    this.subscribeNetStream.play(streamName);
}

Anyway,I’m planning on doing another post to outline my video and voice handshake protocols.  They’re nothing to write home about, but I’d love some feedback if there’s a better way.  I’m also planning on releasing JUICE after I bring it’s level of functionality back up to where the original version was, so stay tuned and you should see my install badge at the bottom of my blog.

Categories : AIR, Actionscript, Architecture, Cold Fusion, ColdFusion Enterprise Server, Flex 3, Messaging, Scalability
Comments (0)
Mar
18

Messaging with Flex/ColdFusion via BlazeDS: Part 2 (Flex configuration)

Posted by: jwd | Comments (0)

This is part two of a two part series. See part one, Messaging with Flex/ColdFusion via BlazeDS : Part 1 (CF configuration)

This installment will go over setting up messaging in Flex, and assumes everything is working correctly on the server. Recall I will be covering two scenarios. A client-publish/client-subscribe model, and a server-publish/client-subscribe model.

Configuring Channels with ActionScript

I prefer defining my channels and channel sets in ActionScript on the client for a number of reasons. It does away with the need for client side configuration files and additional command line parameters that need to be set up each time I check out the project onto a new machine.

A channel is instantiated as follows:

private var pollChannel : AMFChannel = new AMFChannel(“cf-polling-amf”, http://cfserver.domain.com/flex2gateway/cfamfpolling);

The cf-polling-amf corresponds to the channel definition in the services-config.xml file residing on the server. If you gave it a different name previously, or set up a new one, the names should correspond.

The channel set is instantiated as follows:

private var amfChannelSet : ChannelSet = new ChannelSet();

Then, somewhere inside a method (init(), for example) the channel needs to be assigned to the channel set using the addChannel() method. The channel is now ready to use for remoting or messaging.

Publish/Subscribe

There are three classes you’ll use almost exclusively when dealing with AMF messaging. The Producer class, which connects to the messaging channel and is used to send messages. The AsyncMessage class which defines the format of the messages broadcast via the Producer. And the Consumer, which subscribes to the incoming messages received from the server.

The channelSet and destination properties need to be set on the Producer and Consumer, where the destination corresponds to the destination configured in the messaging-config.xml file on the server.

A MessageFaultEvent.FAULT listener can be attached to the Producer to listen for any errors that occur when connecting. And a MessageEvent.MESSAGE listener should be attached to the Consumer to handle messages that are broadcast to the clients.

Finally the consumer must call it’s subscribe method to indicate it is ready to receive messages. A consumer can subscribe and unsubscribe as often as needed.

Publishing a Message

The Publisher sends message to the server in the form of an AsyncMessage. The AsyncMessage class has two properties that we will be concerned with, the headers property and the body property.

The headers property is a dynamic object that you can add any data you want to. In this case we only need to set up one header value (many more are set after you call send() as it moves up the call stack) which is gatewayid. The gatewayid will correspond to the event gateway you set up in your CF Adminstrator.

The body property on the AsyncMessage class is used to send the message payload, and can contain anything. It is an anonymous object, and can have any number of additional properties or objects attached to it.

After setting these properties, the producer calls send, and passes the message as a parameter. The rest happens on the server and in the method that handles the MessageEvent.

Handling the Message Event

Handling the MessageEvent is similar to creating it, only backward. All of the properties that were set when it was published should be there (unless the CFC gateway explicitly removed or overwrote them). Nested in the event is a body and a headers property. They can be accessed as follows:

event.message.body
event.message.headers

And that’s all there is to it.


Server Publish

As previously mentioned, the server can also publish messages. This is different from the previous scenario in the following ways:

1. You only need to set up a Consumer… no Publisher is needed since the client will not be publishing messages.
2. A CFC on the server needs to manually publish the message. This can happen in a variety of applications.

This is accomplished in ColdFusion by setting up the event object, and then passing it in a call to SendGatewayMessage(). Here is some sample code demonstrating:

<cfset data.message = “someObjectOrValue” />
<cfset data.type = "optionalValue" />

<cfset event.body = data />
<cfset event.Destination = "AValidDestination" />
<cfset ret = SendGatewayMessage("anEventGateway", event) />

Other Applications

There are a number of configurations you could have that I haven’t mentioned. A Flex application could publish messages and broadcast to a separate Flex or AIR application that is subscribed to the same channel. There are a variety of methods available to filter messages received.

I’ve only just scratched the surface in getting it set up. What I’m excited for is for an RTMP library to become available, as Adobe announced plans to open source it in the first half of this year. We’ll see how that turns out.

Categories : AIR, Actionscript, BlazeDS, Cold Fusion, ColdFusion Enterprise Server, Flex 3
Comments (0)
Mar
17

Messaging with Flex/ColdFusion via BlazeDS : Part 1 (CF configuration)

Posted by: jwd | Comments (0)

I just went through setting up Flex / ColdFusion messaging via BlazeDS, and have come through it rather unscarred considering it’s my first time using Flex messaging. Most of the documentation I have regarding messaging is biased toward Java (including the sample apps included with BlazeDS). A lot of what I found online, though very helpful, didn’t really apply to the way I wanted to do it. I’m going to document some of the steps here in the hopes that it may be helpful for others (2 parts).

Here are a few details about my configuration that may help you determine if this post might be helpful to you.

  1. When I create a new Flex project, I always leave the “Application server type” set to “None”. This helps me to create applications that can be used against multiple server types.
  2. My ColdFusion server isn’t running on the same server I develop on, nor is it usually the same server I serve my production SWFs from.
  3. This assumes you have BlazeDS correctly set up with ColdFusion, and all of your configuration files (messaging/proxy/remoting/service-config.xml) roughly the same as the default ones included in the BlazeDS distribution (note: there are special ones included for ColdFusion).. If you need help installing and configuring BlazeDS with CF, go here: http://labs.adobe.com/wiki/index.php/BlazeDS:Release_Notes .
  4. I will be going through 2 scenarios on the client side. First, is a standard publish/subscribe setup, where the clients publish and subscribe. Second, a situation where the client only subscribes, relying on the server to do all the publishing.
  5. I don’t maintain any of the above mentioned configuration files in the project, electing to manually instantiate my channels/channel sets in ActionScript.

Setting up services-config.xml

The services-config.xml file already contains a channel definition named “cf-polling-amf”. It can be used as-is if you want your poll interval to be 8 seconds. To change it, set the <polling-interval-seconds> tag to the desired interval.

Setting up messaging-config.xml

Next open the messaging-config.xml file. Here is where you set up your adapters and destinations. If the line isn’t included under the <adapters> tag, you will need to add it”

<adapter-definition id="cfgateway" class="coldfusion.flex.CFEventGatewayAdapter" default="true" />

The default destination “ColdFusionGateway” as configured is sufficient for this post. If you set up your own, there are three tags you will need to define:

  1. <adapter>, this should refer to the adapters defined in messaging-config.xml, usually set to cfgateway.
  2. <gatewayid>, this can be set as a wildcard (*) meaning the client will define it, or you can set it to a specific gatewayid (which I will explain how to set up shortly)
  3. <channel>, which refers to one of the channels defined in services-config.xml, in this case “cf-polling-amf”.

Setting up a gateway CFC

An event gateway is tied to a specific CFC file, and is configured in the ColdFusion administrator. First we will set up two CFC classes. One will be used in our client-broadcast/subscribe setup, the other in the server-broadcast/client-subscribe setup.

The basic client-broadcast/subscribe CFC should look like the following:

<cfcomponent output="false">
  <cffunction name="onIncomingMessage" access="remote" returntype="struct">
    <cfargument name="event" type="struct" required="true"/>
    <cfreturn event.data />
  </cffunction>
</cfcomponent>

It’s important that it has that name, and accepts and returns a struct-type. It’s perfectly OK to process the headers or do whatever it is you need to do before the return value is broadcast.

The server-broadcast/subscribe CFC should look like the following:

<cfcomponent output="false">
</cfcomponent>

Complicated, I know, but try not to cry…

Setting up the event gateway

Login to your ColdFusion Administrator and expand the “Event Gateways” tab. From the menu select “Gateway Instances”. Fill in the following fields:

  1. GatewayID. You will use this either in your messaging-config.xml, and/or in your Flex application.
  2. Gateway Type. Select “Data Services Messaging”. It should be there if BlazeDS is set up correctly with ColdFusion.
  3. CFC Path. Enter or browse to the absolute path of the CFC that will handle this gateway’s requests.

Since we’re using the messaging-config.xml, there’s no need to select a configuration file; and leave the startup mode to auto. If you created both CFCs as described above, then you will need to configure a separate gateway instance for each of them.
Once you restart the server, ColdFusion is set up for messaging.

Continued in part two: Messaging with Flex/ColdFusion via BlazeDS: Part 2 (Flex configuration)

Categories : Actionscript, BlazeDS, Cold Fusion, ColdFusion Enterprise Server, Flex 3, Messaging, Windows Server 2003
Comments (0)
Oct
13

Error #2044: Unhandled IOErrorEvent; text=Error #2038: File I/O Error.

Posted by: jwd | Comments (4)

I started this post a few months ago while I was working on an AIR application that uploads files to a remote server (by way of an upload script).  I ran into this error, Error #2044: Unhandled IOErrorEvent; text=Error #2038: File I/O Error,  which caused me considerable grief until I discovered the simple solution.  I got the same error in an application I was working on today, and so decided to finish this post.

I looked up the problem when I first encountered it, and there seemed to be a consensus that the problem was due to using a bad URL for the location of the upload script.  That was actually the case for me today, so I was able to fix it right away.

When I encountered the problem a few months ago, you could say that it was from using a bad URL, but it was much less obvious.  I had written the upload script in ColdFusion, hosted on a CF server.  I was certain that I had the URL typed correctly because I could access it in my browser.  I discovered over an hour later that I had an authenticated session that allowed me to see it in the browser, a privilege not shared by the AIR app.

The problem was ultimately remedied by placing a special Application.cfc in the upload script’s directory that did away with the requirement for any session variables.  This particular case may have been due to a combination of the CF server’s settings and the fact that I was using AIR, and not a Flex app that might have been served from the same server as the upload script.

Categories : AIR, Actionscript, Cold Fusion, ColdFusion Enterprise Server, Flex 3, Uncategorized
Comments (4)

Search

Feedburner

Subscribe to

Get the latest updates delivered via email

Calendar

September 2010
M T W T F S S
« Jul    
 12345
6789101112
13141516171819
20212223242526
27282930  

Archives

  • July 2010 (1)
  • June 2010 (2)
  • May 2010 (1)
  • February 2010 (11)
  • January 2010 (3)
  • December 2009 (5)
  • November 2009 (1)
  • August 2009 (8)
  • July 2009 (8)
  • May 2009 (4)
  • April 2009 (1)
  • March 2009 (6)
  • January 2009 (1)
  • November 2008 (4)
  • October 2008 (5)
  • September 2008 (1)
  • August 2008 (5)
  • July 2008 (1)
  • June 2008 (2)
  • May 2008 (8)
  • April 2008 (5)
  • March 2008 (2)
  • February 2008 (3)
  • January 2008 (1)
  • December 2007 (6)
  • November 2007 (9)
  • October 2007 (1)
  • September 2007 (2)

Categories

Tag Cloud

adobe apache Architecture book review C++ centos client server architecture Custom Components database Design error message fedora flash catalyst flex Flex 3 Flex 4 fms iis 6 Interaction Design load balancing master-master master-slave mod_proxy_balancer Monkey Patching MySQL no protocol p2p peer to peer Perl PHP Red5 regex replication self registration selinux Shell Scripting shortcut manager skins socket policy file sockets states stored procedures stratus tools workflow

Coworkers

  • Casey Jackman
  • Sean Murphy

Family

  • Emily & CJ
  • Family Blog
  • Gary Dusbabek

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

RSS FlexExamples

  • Styling the text selection format on a Spark TextArea control in Flex 4
  • Setting the scale mode on a Spark Image control in Flex Hero
  • Setting the fill mode on a Spark Image control in Flex Hero
  • Setting a bitmap image fill on a Spark Form container in Flex Hero
  • Setting a bitmap image fill on a Spark FormHeading control in Flex Hero

Spam Blocked

847 spam comments
blocked by
Akismet

Sponsored Links

JUICE Chat

BYU Adobe Users Group


Copyright © 2010 All Rights Reserved
Flexx Theme by iThemes
Powered by WordPress