Prerequisites:
• Intermediate/Advanced AS3 knowledge
• Flex 3
• Flash Media Server
Resources:
• View source files
• Download source files
This tutorial builds on the previous Simple Chat tutorials and concepts from the Adobe FMS Server-Side component architecture.
The main addition to the code has been the introduction of users.asc, which is responsible for handling all user related data and events (in much the same way as chat.asc handles all message related data/events). The user is now automatically assigned a username on connecting to the application, and other users are notified of their arrival and departure in a users list. Users have the option to change their username, and their username now appears above their messages in the message text area.
Hopefully by this point a lot of the code and concepts in this version are quite familiar from the previous tutorials, so I’m thinking if you just download this one and have a play with it, the new additions and their function should be fairly self explanatory.
I’ve added (what are hopefully) fairly lightweight comments to the code to hint at the purpose and the types of the more important functions, and have stripped it down to the bare necessities, so I reckon if you’ve done ok with the first two then you’ll probably get your head around this one in no time.
If you have any questions about this one though please feel free to leave me a comment and I’ll consider expanding this post to cover the topic.
Actually, here’s one bit of code that I do think’s worth mentioning. Notice how the sendMessage function in our example simply stores and passes a reference to the user object and the message string:
{
this.history.push( {user: user, mesg: mesg } );
while ( this.history.length > this.histlen )
this.history.shift();
this.message_so.send( “onSendMessage”, user, mesg );
}
…this allows the Server-Side code to store the necessary data without making any assumptions about how your view wishes to present it. Presentation is instead handled by Flex in applicationComplete.as like this:
{
messagesTf.text += user.username+” says:\n”+mesg+”\n\n”;
messagesTf.validateNow();
messagesTf.verticalScrollPosition = messagesTf.maxVerticalScrollPosition;
}
If you want to add text formatting or extra wording to your messages, you should do so in the view code like this and keep your data clean, not like the Adobe component example below where they add all sorts of formatting to their message/client data on the Server-Side:
var cglobal = this.getClientGlobalStorage(client);
mesg = this.hiliteURLs(mesg);
var hexColor = “#”+cglobal.usercolor.substring(2, cglobal.usercolor.length)
mesg = “<font color=\”" + hexColor + “\”><b>” + cglobal.username + “: </b>” + mesg + “</font><br>\n”;
this.history.push( mesg );
while ( this.history.length > this.histlen )
this.history.shift();
this.message_so.send( “message”, mesg );
}
How nasty is that..?!
May 30, 2009 at 1:12 am |
This is great!
Can you provide some ideas on how to add sometype of “action queue” per user? The idea is to be able to tag a chat message for a user that may not be in the chatroom yet and have the message go into their action queue for them to see when logged into the chatroom.
Whatcha think?
Thanks,
CJ
June 15, 2009 at 9:48 am |
thanks CJ! Have gone a bit off the boil on this due to being really busy on other projects, so sorry for the late/brief reply.
Sounds like you’re after MSN chat ’send an offline message’ type behaviour? If so:
- Make sure the chats created are stored in persistent shared objects so their state is retained on the server.
- Users will need login details (rather than anonymous chat)
- Users will need a friends/contact list in order to initiate offline chat.
- You may wish to create a conversation object when a new chat is initiated. This could contain an array of timestamped message objects with ‘from’ and ‘to’ properties. The conversation object could contain extra state properties so you can tell which users have looked at it and which haven’t.
- Ideally these conversations would be stored in a database and would be query-able by user id, but I’m afraid I currently don’t have any experience as yet integrating FMS with databases.
Its a tricky problem so I’d advise sitting down with a pen and paper and noting down all of the functionality you require. Once you’ve got a full picture of the stateful data you’re interested in retaining then you could draw a simple UML diagram planning out which properties should go on which objects. I find this approach really helps to keep my code tidy and saves a lot of time/energy in the long run.
Good luck!
rob
September 1, 2009 at 10:02 am |
Hi Rob,
Its a Gr8 idea about Chat, rob i had developed a a/v chat and now i want to integrate whiteboard with this chat application.
would u plz guide me, how to start and where to go for whiteboard integration with flex audi/video chat.
regards
Amar
October 1, 2009 at 8:48 am |
Hi Amar, sorry for the slow reply- have been on holiday. I’ve not built a whiteboard app yet I’m afraid and I’m a little rusty at this now as I haven’t played with it for some time. Sorry I can’t be more help.. best of luck though!
September 30, 2009 at 9:04 am |
Hello
——>netStatusHandler:
level = “status”
code = “NetConnection.Connect.Success”
objectEncoding = “3″
description = “Connection succeeded.”
data = “”
——>netStatusHandler:
level = “error”
code = “NetConnection.Call.Failed”
description = “Method not found (chat.getHistory).”
I have this trouble, please guide, thanks very much to you.
Br
Hai
October 1, 2009 at 5:19 am |
Hello
I have a comment and hoping for your help, but you deleted it ?, please help me, my debug like below:
Server feedback -> When I run your package
——>netStatusHandler:
level = “status”
objectEncoding = “3″
data = “”
code = “NetConnection.Connect.Success”
description = “Connection succeeded.”
——>netStatusHandler:
level = “error”
code = “NetConnection.Call.Failed”
description = “Method not found (chat.getHistory).”
Detail:
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetConnection was unable to invoke callback onBWDone. error=ReferenceError: Error #1069: Property onBWDone not found on main and there is no default value.
at main/applicationComplete()
at main/___main_Application1_applicationComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.managers::SystemManager/preloader_preloaderDoneHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::Preloader/displayClassCompleteHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::DownloadProgressBar/timerHandler()
at mx.preloaders::DownloadProgressBar/initCompleteHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::Preloader/dispatchAppEndEvent()
at mx.preloaders::Preloader/appCreationCompleteHandler()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.core::UIComponent/set initialized()
at mx.managers::LayoutManager/doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()
at mx.core::UIComponent/callLaterDispatcher()
Thank you very much, and help me
Br
Hai
October 1, 2009 at 5:22 am |
And more information at adminuistration Console:
Starting Live Service…
Found wildcard (*) entry: disabling authentication for HTML file domains
Found wildcard (*) entry: disabling authentication for SWF file domains
…loading completed.
Accepted a connection from IP:127.0.0.1, referrer: file:///C|/Program Files/Adobe/Flash Media Server 3.5/webroot/live_recorded/main.swf, pageurl:
Sending error message: Method not found (chat.getHistory).
October 1, 2009 at 8:58 am |
Hi Nguyen,
I didn’t delete your comment, it required approval before appearing on my blog.
I’m afraid I’m pretty rusty at this now as I blogged this over a year ago and unfortunately haven’t really had the time to play with it more since.
Its sounds like your Java code hasn’t been compiled correctly or is located in the wrong place. I’m afraid I can’t really help at the moment as it will take me hours/days to get back into this and I’m really busy lately.
Good luck with it though.
cheers
rob