Showing posts with label flex. Show all posts
Showing posts with label flex. Show all posts

Saturday, August 1, 2009

AmFast adds support for Google App Engine and Django

I just released version 0.4.0 beta of AmFast, a Flash remoting package for Python. The new release includes support for Google App Engine and the Django framework.

Browse the code here.


Check out the live Google App Engine demo.


To get the code:
svn checkout https://amfast.googlecode.com/svn/tags/0.4.0b

Wednesday, May 20, 2009

Real-time Flex messaging with AmFast

This example is very similar to the previous, but we're going to use AmFast's HTTP streaming channel to implement real-time flex messaging. Get the complete example code here.

First let's setup the Producer and Consumer in Actionscript.


// Configure the ChannelSet that
// messages will be sent and received over.
import mx.messaging.ChannelSet;

// To use HTTP streaming, the
// StreamingAMFChannel class must be used.
import mx.messaging.channels.StreamingAMFChannel;
var channelSet:ChannelSet = new ChannelSet();
var channel:StreamingAMFChannel = new StreamingAMFChannel("channel-name", "server-url");
channelSet.addChannel(channel);

// Setup a Consumer to receive messages.
import mx.messaging.Consumer;
var consumer:Consumer = new Consumer();

// The consumer's destination is the 'topic'
// name that the consumer will be subscribed to.
// The consumer will receive all messages
// published to the topic.
consumer.destination = "topic";

// Use the ChannelSet that was already created.
consumer.channelSet = channelSet;

// This event listener will be called whenever
// the consumer receives a message from the server.
consumer.addEventListener(MessageEvent.MESSAGE, newMsgHandler);

// The consumer won't start receiving messages
// until it is subscribed.
consumer.subscribe();

// Setup a Producer to publish messages.
import mx.messaging.Producer;
var producer:Producer = new Producer();
producer.destination = "topic";
producer.channelSet = channelSet;

// Create an Async message and send it
// to all other clients subscribed to the topic.
import mx.messaging.messages.AsyncMessage;
var msg:AsyncMessage = new AsynMessage();

// Set the message's body attribute to the
// object that is going to be published.
//
// In this case the object contains
// the X and Y coordinates of a Sprite.
msg.body = {'x': 10, 'y': 10};
producer.send(msg);

Next we'll setup the server.

# Create a ChannelSet to serve messages.
from amfast.remoting.channel import ChannelSet
from amfast.remoting.wsgi_channel import StreamingWsgiChannel
channel_set = ChannelSet()

# Each individual ChannelSet can use
# one or more Channels. When messages
# are published through the ChannelSet,
# they will be published to all subscribed clients,
# regardless of which Channel the clients
# are connected through.

# Create a HTTP streaming channel.
#
# When a client connects to a streaming channel,
# the HTTP connection remains open until the client
# disconnects. When messages are published,
# they are immediately dispatched to clients connected
# to HTTP streaming channels.
stream_channel = StreamingWsgiChannel('stream-channel')

# WsgiChannels objects are wsgi applications
# that can be served with any Wsgi server.
# CherryPy is being used in this example.
cherrypy.tree.graft(stream_channel, '/amf')

# Start the server.
# App() is your root controller class
# for non-AMF functions.
cherrypy.quickstart(App(), '/')

# That's it, our server is up and running.
# It's that simple.

To test the example, download the full code from the repo. To run the example you'll need to install AmFast and CherryPy or Twisted 1st.

# To server the example with cherrypy
python cp_server.py

# To server the example with Twisted
twistd -noy twisted_server.tac

Open two browser windows and browse to 'http://localhost:8000'. Click the 'Subscribe' button in both windows. In the 1st window click on the 'Master' button. In the 1st window, click on the yellow circle, and drag the circle around the screen. As the circle is dragged around the screen, the position of the circle will be updated in the 2nd window. Pretty cool stuff.

Friday, May 15, 2009

'Pushing' messages to Flex clients with AmFast

One of the coolest aspects of Flex development is the ability to 'push' messages from the server to clients. With the newest release of AmFast, you can finally utilize this capability with all of the goodness of Python. This will be the 1st of 3 posts describing how you can use the AmFast Flash remoting package to push messages to Flex clients from a Python server.

AmFast supports pushing messages to clients over HTTP using 3 different strategies: polling, long-polling, and streaming. Here is a good article describing the differences between those strategies. Go ahead and skip past the XML configuration sections, since you won't need any XML to configure AmFast :)

Streaming channels deliver messages in real time, but also consume the most server resources. Standard polling consumes the least amount of server resources, but is also the slowest of the three strategies. Long-polling sits in the middle and offers a nice compromise between latency and resource consumption.

AmFast has built-in support for using any of the 3 messaging strategies with either a multi-threaded WSGI server, or the Twisted web framework. One thing to think about when implementing a multi-threaded server is that any client using long-polling or streaming may consume a thread for a significant amount of time, even if all it's doing is waiting for a new message. I haven't done any tests, but I'm guessing that Twisted's single-threaded, asynchronous design can handle more concurrent connections then a multi-threaded implementation.

On the client side, the Actionscript Consumer class is used to receive messages from a server, and the Producer class is used to send messages to a server. Any type of object can be pushed to clients, so the same technology can be used to build many different types of applications.

In the next post I'll explain the details of using AmFast's HTTP polling and HTTP long-polling channels to create a simple chat client. In the following post I'll show an example of using HTTP streaming to create an app where a master client can manipulate a graphical entity on the screen, and changes are replicated to all other subscribed clients.

Sunday, March 22, 2009

AmFast 0.2.2 Released!

The latest version of AmFast is out. Improvements include an Actionscript code generator, an example using the Twisted framework, and several bug fixes.

Wednesday, March 11, 2009

AmFast 0.2 Released!

Check out the latest version of AmFast. The 0.2 version implements AMF0, AMF3 and supports configurable remoting with NetConnection and RemoteObject.

It's fast, flexible, and easy to use.

Tuesday, February 10, 2009

AMF vs. JSON

You can find many blog posts comparing AJAX data transfer formats JSON and XML to AMF3, but they all seem to miss what I see as the 3 biggest advantages to AMF3.

1: AMF3 supports references for objects, strings, and class definitions. If you're encoding an object graph that contains references to the same object over and over, or even the same object type over and over, AMF3 will be significantly smaller over the wire, and once you get the data you won't need to do any manually reconciling of objects that are really the same thing.

2: AMF3 can decode typed objects that have methods, derived properties, and a static class definition. That saves time because you have to do less post-parsing processing of the data. It also makes development a lot quicker, especially if you're using an ORM on the server side. You can send objects retrieved from the database straight over to the client, the user can modify the objects with the GUI, and the objects can be sent straight back to the server to save changes. Your server-side AMF encoder/decoder library and ORM library take can care of all the CRUD grunt work, so all you have to do is figure out a decent data model and how to represent it in the client GUI. I use Python and PyAMF on the server side, which even has support for lazy-loading attributes of objects persisted with the SQLAlchemy ORM.

3: You can implement the IExternalizable interface on any AS3 class to fully customize the object encoding/decoding process. If you're brave and need optimization for large data sets, you can even write and read directly to/from the AMF3 byte stream and use your own custom encoding scheme suited for your data type

Thursday, January 22, 2009

PyAMF SQLAlchemy Adapter

PyAMF 0.4 was recently released, and the new code contains SQLAlchemy support by default, plus a bunch of other cool new features and bug fixes.

Check out my example Flex/PyAMF/SQLAlchemy project for ideas of how to get started with PyAMF and SQLAlchemy.

Monday, August 25, 2008

Flex JSON-RPC implementation

So, you're checking out Flex and you're thinking to yourself, "Gee this e4x stuff is pretty rad, but it's 2008 and I could really use a good JSON implementation so I can integrate my bitchin' Flex component into my AJAX page." Amazingly, I was thinking the same thing, so I put together a couple of classes to implement a JSON-RPC v1.1 client.

The application code for this post is available on Google code. In addition to the JSON-RPC classes, the application contains a simple gui with controls for testing and logging JSON-RPC communication. To compile the code, you'll also need as3corelib in your compile path, which handles the JSON serialization/deserialization.

The 1st thing you'll need is a JSON-RPC server. If you don't already have one, it shouldn't be too difficult to put together. Follow this tutorial to create a simple Python JSON-RPC server, or use any 1.1 compliant server.

Next, we need to extend mx.rpc.AbstractOperation. This class will send the method invokation to the server and decode the result. Two important methods are overriden. The first is 'send', which will encode the request according to the JSON-RPC v1.1 spec, create a HTTPRequestMessage, and then call the parent invoke() to send the message to the server. If JSON encoding fails, a FaultEvent must be dispatched. Use the parent method dispatchRpcEvent() to make sure the event is dispatched by both the service and the operation.

The other important method is 'processResult', which decodes the response from the server and checks for any errors defined by the server application. The 'processResult' method is in the mx_internal namespace. If you're not familiar with using mx_internal, you should probably read up on it. The parent class takes care of most of the heavy lifting, but you will need to dispatch a FaultEvent if the JSON decode fails, or if a server application error was defined. Set the _result variable equal to the decoded result, and you're good to go.

Finally, we need to extend mx.rpc.AbstractService. This class is used to instantiate mx.rpc.AbstractOperation instances and invoke remote method calls in our application code. The class's main purpose is to act as a proxy that intercepts method calls, so we will be able to invoke a remote method with the syntax: service.method(arguments) instead of operation.send(method, args). You will need to override the 'getOperation' method to instantiate the correct mx.rpc.AbstractOperation subclass.

Here's how the jsonrpc.JsonRpcService can be used in your application code to communicate with the server:

import mx.rpc.events.*;

import jsonrpc.JsonRpcService;

private function callFoo(fooArgs:Object):void
{
// Create service object and
// call remote method 'foo'.
var jsonService:JsonRpcService = new JsonRpcService();
jsonService.rootUrl = 'http://localhost';
jsonService.url = 'test';
jsonService.addEventListener(ResultEvent.RESULT, gotBar);
jsonService.foo(fooArgs);
}

private function gotBar(event:ResultEvent):void
{
event.target.removeEventListener(ResultEvent.RESULT, gotBar);
var bar:Object = ResultEvent.result;
// do something with bar
}

Saturday, August 23, 2008

Flex360

We've been using Adobe Flex for the past 6-months to develop SLiM, our RIA client to access our backend GAPSS LIMS server. Flex is the perfect fit for LIMS, because we can do really cool stuff, such as performant drag and drop plate maps right in the browser.

I got my first chance to interact with the larger Flex community this past week at Flex360 in San Jose. I was half-expecting to meet a gaggle of converted Flash developers of the 'creative' type, but I was pleasantly surprised by the number of attendees using Flex for enterprise level applications. Many big companies are developing internal apps with Flex, and most of the community seemed to be very high quality.

Overall, the conference re-enforced the decision to use Flex for our app. I learned a ton of new technical info at the sessions and I'm trying to prioritize what was coolest, so I can go back and re-code sections of SLiM to be better.