NFC Flash Chat

While I am not a big "chatter," building a chat application was a nice way to play with some of the new Flash 5 features and prototype some new ideas I've had about designing applications with Flash. This framework can be used to build other real-time, multiuser Flash applications. I'm interested to hear what you think of all this and am happy to answer questions. Send email to alon@ajdigital.com.

Overview

This is a Flash chat client for the Java chat server NFC Chat, located at http://nfcchat.sourceforge.net. It is available for you to download, pull apart and use. There are three main pieces to this Flash application:

Using the ChatEngine

You should load nfcEngine.swf in to your own Flash movie that provides all your interface elements. It does not matter where you load this movie as it will set a variable _root._ChatEngine when it loads that points to itself. The interface should only reference the engine through this variable, as in _root._ChatEngine.sendSignOn(username,password);

Likewise, your interface file should set a variable at the root that points to the location of the Handler clip:
_root._ChatInterface = this;
The chat engine uses this variable to communicate with the interface. nfcUI.fla does this on the first frame of the movie.

Sending messages

When you call a function in the chat engine to send a message, the engine builds the appropriate message format, creates an XML document object and sends it through the socket it has opened with the server. None of these functions have return values. All messages sent back from the server must be received and processed using the available handlers. You just need to call the functions:

_root._ChatEngine.sendSignon(username, password)
Connect and login in to the server. Password not required.
_root._ChatEngine.sendSignoff()
Log off.
_root._ChatEngine.sendStats()
Request server stats
_root._ChatEngine.sendGetRoomsList()
Request list of all rooms
_root._ChatEngine.sendJoinRoom(room)
Request to join a room
_root._ChatEngine.sendUserInfo(username)
Request user stats
_root._ChatEngine.sendGetUserList()
Request list of all users
_root._ChatEngine.sendRoomMessage(room,message)
Send message to a room
_root._ChatEngine.sendRequestUsersInRoom(room)
Request list of users in a room
_root._ChatEngine.sendPartRoom(room)
Leave a room
_root._ChatEngine.sendSayToUserMessage()
Send a private message to a user
_root._ChatEngine.sendEmoteToRoomMessage()
Emote to a room
_root._ChatEngine.sendEmoteToUserMessage()
Emote privately to a user
_root._ChatEngine.sendHelpMessage(command)
Not very useful - request help info on an NFCChat command
_root._ChatEngine.sendVersionMessage(version)
Not very useful but nice to do - tell the server what kind of client you are
_root._ChatEngine.sendKillMessage(user,message)
Kill a user - not sure what this actually does
_root._ChatEngine.sendIgnoreMessage(username)
Tell server to not send messages from a specifc user to us
_root._ChatEngine.sendUnIgnoreMessage(username)
Tell server to start sending messages from a specifc user

Receiving messages

The server sends messages to the chat client, sometimes in response to messages you have sent, and sometimes because of other users' actions (like saying something to a room). When server messages come in, they are received by the chat engine, parsed and processed before the engine calls these functions in the interface. These are the functions you will need to use or tweak to build the interface:
_root._ChatInterface.Handler.handleConnect()
Connected successfully to the chat server
_root._ChatInterface.Handler.handleFailedConnect()
Failed connecting to the chat server
_root._ChatInterface.Handler.handleClose()
Connection to the chat server is shut down
_root._ChatInterface.Handler.handleSignon()
Acknowledgement of successful logon
_root._ChatInterface.Handler.handleError(error)
Something went wrong
_root._ChatInterface.Handler.handleUnknown(array)
We received a message type we did not recognize, input is an array
_root._ChatInterface.Handler.handleNoAction(message)
We received a message with no action (server & user stats)
_root._ChatInterface.Handler.handleRoomJoin(room)
Acknowledgement of successful room join
_root._ChatInterface.Handler.handleRoomMsg(sender, room, message)
Received a message from a sender to a room
_root._ChatInterface.Handler.handleRoomUserDiff(room, diff, username)
A user left or joined a room, diff = + or -
_root._ChatInterface.Handler.handleServerUserList(users)
Receive a list of all users
_root._ChatInterface.Handler.handleServerRoomList(rooms)
Receive a list of all rooms with number of users in each, as in (room1, 2, room2, 4, room3, 0)
_root._ChatInterface.Handler.handleRoomUserList(room, users)
Receive list of users in a room
_root._ChatInterface.Handler.handlePartRoom(room)
Acknowledgement of leaving a room
_root._ChatInterface.Handler.handlePrivateMsg(sender, message)
Receive private message from a sender
_root._ChatInterface.Handler.handleRoomEmote(sender, room, message)
Receive a message emoted to a room
_root._ChatInterface.Handler.handleUserEmote(sender, msg)
Receive private message emoted from a sender
_root._ChatInterface.Handler.handleKill(killer, msg)
Handle being killed by a user who also sends a message, I haven't seent this happen yet
_root._ChatInterface.Handler.handleUserDiff(username, diff)
Handle a user arriving or leaving the chat
_root._ChatInterface.Handler.handleRoomDiff(room, diff)
Handle a room being added or removed
_root._ChatInterface.Handler.handleShutdown()
Server shut down

Thoughts

What's this about?

I had a couple goals in initiating this project:
  1. To play with and learn some of the new Flash 5 features
  2. To prototype ways to build Flash apps so that funcionality is independent of interface
  3. To build reusable interface components that can be used by a range of applications
I feel somewhat successful with the first two. Your efforts to use this implementation to tweak or create new interfaces will be a good test of number 2. The third has not been a high priority on this project and therefore I haven't done much with it. The lists in the interface I provide are a start with this.

Simplify

While the nfcUI.fla interface is pretty full featured. The chat engine could be used to make a much simpler chat that only takes a login and has just one room. All you need to do is send and recieve the messages you want to use and ignore everything else. If I get a chance, I'd like to put together a sample of this.

Add Chat to All Your Flash

Because the chat engine and interface create their own references by which they communicate, you can create a chat program to load in to your other Flash apps. It would be cool to be playing a Flash game and be able to send messages to all the other players. You can do that with this implementation.

Debugging

To debug while authoring, I use trace a lot. In fact, if you load and use the nfcEngine.swf file while testing your movie, you will see a lot of stuff written to output. I try to use trace messages that look like:
    trace(this + ": whatever you want to say");
"this" resolves to the path to the movie clip creating the trace message so that it's easy to see where it's coming from. Messages from the nfcEngine will have a movie clip path dependent on where you load the movie. To hide these messages or reduce the size of the .swf created, select to remove trace actions in your publish settings.

Bugs

As with all works in progress, there are a few bugs. I'm not concerned with interface bugs but more with bugs in the handling of communication with the chat server. I'll list known problems here and fix them when I can.

The Chat Server

I have a chat server running at www.ajdigital.com. This server is only for development and testing. I will not guarantee it's stability or reliability, but you are welcome to test against it.

The chat server is called NFC Chat and is an open source Java chat server. More information and source code is available at http://nfcchat.sourceforge.net.

I chose this server because it is open source, well designed, full of features, and easy to extend. You can add new message types, tweak the code, or, as I did, look at how it is implemented and add your own code to it.

Made "Flashable"

I extended the chat server to change the format in which it sends messages. Flash requires that all socket messages are sent and received in XML format. I just wrapped the default NFC messages in simple XML. Essentially, instead of sending and receiving messages that look like:
    /saytoroom  chatroom    hi, guys!
The messages now look like:
    <message value="/saytoroom  chatroom    hi, guys!" />

These changes I made require no modifications to the source provided on SourceForge - they simply extend the existing application with new functionality. They are in SourceForge CVS in web/flash/ if you want to grab them there and will be available in the build following release 1.0.6-rc2.

License

I am distributing the chat engine under the GNU General Public License (GPL) which pretty means you can do anything with this stuff except sell it to someone else without getting my permission. You can do absolutely anything you want with the interface. If you want to use this stuff in your own work and/or sell it as part of your work, all you need to do is ask.