Thursday, December 14, 2006

VO Objects and a Command Pattern in Flex

I'm doing a bunch of experimenting with a sort of AJAX style Flex Client-Server implementation.
Basically, I'm setting up a one-way socket connection from the server to the client, sending an int of the size of an AMF3 object, followed by that object. (in c#.net using flourine), and if I don't need to send another object, the connection is keep-alive, so I just don't send it. A use case of this is any real-time network based application such as chat, or a networked game such as pong. Its less expensive to keep a connection rather than make a new one over and over. This is an excellent way of accomplishing Server-Push for applications where the client isn't sending data to the server that often, but is receiving it very often. (so no polling protocol is required)

The flex client reads an int SIZE, then waits for that many bytes to be available, then reads an AMF3 object, casts it to a type MessageVO, and then calls interpret on it.

[code]
package vo {
[RemoteClass(alias="vo.MessageVO")]
public class MessageVO { public var type:Number; public function interpret():void { } }}
[/code]

We can then have many different types of messages, each who's client implementation has a fleshed out interpret method, but who's server implementation has only the members defined.

For example:

import model.ModelLocator;
package .vo {
[RemoteClass(alias="vo.ChatMessageVO")]
public class ChatMessageVO extends MessageVO {
public var message:String;
public var fromUserID:Number;
public function interpret() { ModelLocator.getInstance().chatMessages.push(this); }
}
}

When flex reads the amf object, and calls interpret on it, flex knows the object type is a ChatMessage underneath the covers, so the implemented interpret method in the ChatMessage class is called, and the singleton ModelLocator gets a new chat message in the chatMessages array. (Which other classes are binding to).

I'm also debating making a new event type of MessageReceivedEvent which contains the message that was received, so anyone can listen for events that they broadcast.

I'm working on a very modular architecture at the moment, modules need to be able to implement a pattern and expect other modules to adhere to this pattern for interoperability, so I'm testing out a bunch of different patterns to see what will work best across the categories of development time, runtime execution, 3rd party implementation time.

Tomorrow I'll have a networked version of that pong app using this pattern available, additionally you will be able to chat with your opponent.

No comments: