Clustering with Red5

July 28th, 2011 by Paul Gregoire

Once your service out grows its original space, you will most likely look at adding clustering capabilities. While clustering an application may seem daunting, it can be done in a fairly simple manner at first. Whilst at Infrared5, I have created several clustered applications using the methods which will be supplied below and now may be added to your skillset.

For this example you will need the following software (IDE’s not listed):

Herein we will go over clustering a simple chat application; both the client and server code in this example consist of only two to three source files respectively. Code blocks may not contain all of the code or comments to keep the sections short and focused.

Server-side (Java)

The first piece of code we need is the Red5 application adapter, it is used by the server to control the lifecycle of your application. In many cases, the base classes may be configured via Spring so that you don’t even need to write your own for simple applications; as an example, the SOSample demo that comes with the server doesn’t have any code for an application adapter. For this application we will override two lifecycle methods to handle the starting and stopping of the application. When the application starts, we need to start our cluster client class and join the cluster. On stop we disconnect from the cluster and perform any clean up necessary.

We must also add any methods which will be called by the client, which in this case would be one that accepts a sender name and some text.

Pretty easy looking isn’t it? Being a standard Java method, it could accept these values from anywhere that has access to the method such as a servlet. Next up, on the server-side is the code to send and receive messages on the cluster. This “ChatRegistry” extends the ReceiverAdapter provided by JGroups and is implemented in the most minimal way I could think of.

You may have noticed we’ll be using UDP for this example, I have found that this is the easiest way to setup JGroups and keep all the nodes communicating on a local network.

Last but not least for the server application we have our model class to hold a creation time, sender name, and the chat text itself.

The Actionscript twin for this model will be shown in the next section.

Client-side (ActionScript)

I used FlashBuilder to whip-up a quick chat client, so don’t bash my code too hard. For the example clients I created a Flex Project with MXML and one AS3 class file. In the MXML script block besides the connection handling, we need a method for sending and another to receive.

Be aware that the NetConnection.call in the send function must match the signature on the server’s application adapter.
The final class needed on the client is our model, which in Actionscript is a lot less “wordy” than in Java.

I have not included the configuration files and some other things in this post to prevent confusion, but rest assured they are in the source archives at the end.

Running

The quickest way to get up-and-running is to grab the server zip and deploy it to two servers or vmware virtual machines. Everything you need to run the client and server is in the zip.  After Red5 has started up, look at your console and you should see a line indicating that your application is in the cluster.

Please note that If you are using OSX you may need to add “-Djava.net.preferIPv4Stack=true” to your start-up script due to a bug in JGroups IPv6 handling.

Open browsers on each instance and navigate to http://localhost:5080/chatr/chatr.html

Once loaded, enter a name and click connect. After you have two servers running and clients connected to them, your output should look similar to this when chatting.

So now you know how easy this can be, go forth and create some cool stuff!!

Downloads

Full application with Red5 server (ready-to-run): http://bit.ly/pIoVBi

Client source: http://dl.dropbox.com/u/7316897/red5/chatrclient-src.zip

Server source: http://dl.dropbox.com/u/7316897/red5/chatr-src.zip

, , , , ,

Meet Infrared5′s New CEO – Rebecca Allen

July 26th, 2011 by Chris Allen

As many of you who follow Infrared5’s progress know, we’ve recently created a new company around a product we developed. This company, Brass Monkey, allows a smartphone to become a game controller. We are doing some amazing work, including winning awards, landing clients like LucasFilm, and closing in on a seed round of fundraising. Needless to say, Brass Monkey has been taking more and more of my time and focus over the last year. So the partners and I have decided it is best for me to step down as Infrared5’s CEO.

I’m excited to announce that my business partner and wife, Rebecca Allen, will be taking on the role of CEO for Infrared5. Infrared5 wouldn’t be any where near where it is today without all of her expertise in art direction, customer relations, finance, company operations, project management and overall leadership. She’s actually been acting in this capacity for a year now, and the partners came to the conclusion that it made sense that she officially come on board as the CEO of the company. While Rebecca has been at the helm, the company has continued to flourish and grow even in a down economy.

We are beginning to get many more repeat customers, and we have been and are continuing to look to hire new employees. Rebecca has a knack for keeping customers happy and understanding complex problems. I can’t think of a better person to lead our service based technology business.

With all this said, I will continue to serve as Infrared5 President and be involved on strategic level decisions for the company. We are all excited this year with the growing success of all of our businesses. Please join me in welcoming Rebecca to her new position. Read the rest of this entry »

Working with Native JSON in Flash Player 11

July 21st, 2011 by Todd Anderson

With the recent public release of the next candidates for the Flash Player and AIR runtimes, I wanted to check out one of the features that I had been waiting to see as part of the player for some time. No, not Molehill. Native JSON support! Boring, right? Maybe i’ll address Stage3D (née Molehill) in another article, but initially I am actually more curious to check out the native JSON support.

If you are unfamiliar with JSON, it is lightweight, interchangeable format that is human-readable and has a familiar structure that allows for ease in parsing and generating data. You can read more about it at http://www.json.org.

History… sorta

For applications targeting the Flash Platform, there was a time when you would typically go grab the as3corelib library and use the JSON class to encode or decode JSON data – actually, the time is still now, or until these runtimes are out of candidacy. Though the JSON class from the as3corelib library works well and was a welcome addition to the community, it sits outside of the player globals and is implemented in ActionScript. That’s not to say it is necessarily slow, but – because of its implementation – it is inherently slower than having native support of JSON within the player.

Future… kinda

With the advent of native JSON support in the Flash Player 11 and AIR 3 runtimes, we now are afforded serialization and deserialization at a faster speed as well as an API that matches that of the JavaScript implementation.

JSON API

You can head over to the online docs and check out the JSON API for a deeper explanation, but the JSON class basically has two static methods:

If coming from working with the JSON class from as3corelib, these will most likely look different than the methods you are used to. That’s alright, they do relatively the same thing and, depending on the level of control you want, it may just be a matter of the methods being named differently. I do want to go over what has been made available in these methods in moving toward the use of the native JSON class, however, as they can be quite interesting and possibly useful depending on the design of your application.

JSON.stringify()

The JSON.stringify() method does essentially what you may be familiar with as JSON.encode() from the as3corelib – put object in, get string out. However, the global JSON class of FP11 now has a couple more parameters that can be used to your advantage when turning that object into a JSON string.

The replacer parameter can be supplied as a list of String or Number that correspond to the key-value pairs which you want to serialize to a JSON string. It can also be supplied as a Function delegate that will be invoked upon each key-value pair that allows you to handle the data directly in either modifying the value being generated or – in the case of returning undefined – removing it from serialization.

Here is a quick example of how you can assign a replacer delegate and remove a value from being serialized to the generated JSON string:

That gives you a little peek at the potential that a replacer has when generating JSON, but you can imagine that it could be valuable for, say, hashing passwords and such on the client side before being sent over the wire.

The other parameter in JSON.stringify() – space – can be a String or Number and is used in prettifying the generated JSON string by providing whitespace and readability. Using the previous example, if we provided the value of 4 as the argument for spacer, the trace output would no longer be on one line and look more like this:

Pretty!

JSON.parse()

Let’s take a look at the parse method. Again, if coming from as3corelib JSON, it will probably just be a change of calling:

[FP 11 global: JSON]

instead of:

[as3corelib: JSON]

However, there is a reviver parameter on the parse() method which can be of use if you wish to handle working with the key-value pairs during the parse operation of the value object. The signature of the Function supplied as the reviver should have two parameters defined – key and value – and should return the modified value in order to be stored in the object.

Here is a quick example of using the parse() method with a reviver that turns each string value to upper case:

One thing to note here is that if you return undefined from the reviver delegate, you can actually remove the property and its value from the generated object, which is useful but also is something to look out for if things seem to be going wrong. Another thing to note here is that the last key-value pair passed through this reviver delegate is the actual object itself – keep that in mind when using a reviver and make sure to check that you are not modifying the whole object you are parsing.

Going a step further

Now this new API is well and good and we could be on our way sending and receiving JSON data and punch our time card and grab a beer, but there may come a time where you actually want to have more of a workflow in streamlining the generation and parsing of this data using real model objects in your project rather than generic Objects.

Now it is true that as long as the property values held on a custom object are those that are supported in the JSON format – string, number, boolean, array and null – that you could supply the custom object to the JSON.stringify() method and it will properly generate the JSON object for you. Going the other way – parsing – however, is not going to inherently create or write to that custom object that you may have previously serialized; it will just generate a generic object. Of course there is nothing stopping you from traversing the properties on that object and setting them on a new custom instance, but this is an opportunity in which we might want to think about how we can go about creating a design in which we can easily map back to custom objects. Things I like to think about and bore people with. Don’t fall asleep on me.

To get an idea of what i am talking about, say we have a Person class which serves as a model for a person in the context of our application. It has your basic properties on it which are standard value types – like name, company, etc from previous examples. We can certainly generate a JSON string and pass that around like so:

Now, in our perfect world, that would trace [object Person], wherein the JSON parser was knowledgable to map the object to a Person. There is that reviver parameter on JSON.parse() but that won’t help us much in mapping back to a custom instance as it only handles the key-value pairs and not the object as a whole.

One solution is to serialize the classname down with the generated JSON object, so that when it is received on the client, we can inflate a custom instance based on the associated class. So, if you can imagine, the models you will use in your application all extend a base model that handles setting this classname that is accessible and writable to a JSON object, eg:

In this base model class, there is a model accessor which is the qualified classname of the subclass. It also exposes a description accessor which allows easy access to the list of read-write properties on the subclass. It is marked as transient to denote that it should not be considered enumerable when generating the associated JSON object.

Now that we have our base model, any subclasses will be serialized with a model property representing the qualified clas name which can be used to inflate the custom object upon parse. Modifying the Person class used in a previous example, the class now looks like this:

We just have to remember to call super() in the constructor or ensure that the _clazz property value is that of the subclass. From here, all that is left is using that model property to instantiate a new instance and fill the available property values from the parsed JSON object received. Here is a quick working example:

In the parseToModel() method in this example, we see how the read-only model property is passed in the flash.utils.getDefinitionByName() function to inflate a new instance of the associated model – Person – that was previously serialized to a JSON object.

One thing to remember is that a reference to the class in which you want to use to inflate a new instance of must be compiled into the SWF, otherwise you will get Runtime Errors. There are a couple ways in which you can ensure that the reference is included, and I will leave that up to you to explore.

View and download the example

That is just one solution in implementing the ability to map JSON objects back to custom instances, but I am sure there are many more and I would like to hear your thoughts on them in the comments.

Conclusion

Native JSON support to the runtimes is a much welcomed addition and I am very happy to see it finally become a reality, and it is good to see – in my opinion – an API that matches that of the one on the JavaScript side. Hopefully I covered some of what can be accomplished with it and how it can benefit you in any current or future projects. Go grab the beta players, and the playerglobal SWC and have some fun!

, , ,

Android Graphics and Animation: Part II – Animation

July 19th, 2011 by Keith Peters

Android Animation

In the first part of this series, we covered basic graphics in Android – starting a new Android project, creating a custom view and displaying it, and using that view to draw custom graphics in its onDraw method. To recap, the drawing occured only when the onDraw method was called by the system when it determined that the app needed to refresh its display. This generally occurs once when the app starts and only occasionally, if ever, thereafter. For animation, we need to be able to trigger redraws on a regular basis. This is quite a bit more complex than drawing a static image, but not horribly so, so let’s dive in.

SurfaceView

In the last example, we extended View for our custom view class. That was fine for the purpose, but will not be adequate for drawing multiple times like we need to do for animation. For View, the onDraw method is triggered by the system when it knows that the Canvas is safe to draw on. It can set things up for us before calling onDraw, and then clean up when it is done executing. Since we need to do drawing on our own schedule, we need a view class that will let us do this set up and clean up ourselves. That class is called SurfaceView. So that’s what our new view will extend.

To get started, create a new Android project the same way we did last time. Call the project and activity “Animation”. Again, in the main activity class replace the call to setContentView with a custom view. We’ll call this AnimView:

Of course, AnimView does not exist, so we’ll get an error. Trigger a quick fix, which will offer to create the AnimView class. Before accepting the defaults in the New Java Class dialog, change the superclass field to “android.view.SurfaceView”. When the class is created, trigger another quick fix to create the constructor. You should end up with the following:

At this point, the app should compile and run, but naturally will show just a black screen.

SurfaceHolder

Again, since we will be a lot more in control of when things get drawn, we need to go a little more low level in what we are doing. When using onDraw, you are automatically passed a Canvas object that you are safe to draw on. When using SurfaceView though, you need to get your canvas from something called a SurfaceHolder. This can be retrieved by simply calling getHolder() from the SurfaceView instance. That’s easy enough, but there’s another bit of complexity coming up.

You can’t draw to a surface of a SurfaceView/SurfaceHolder until the surface is created. And you should not draw to it after it has been destroyed. So we need to know when these things happen. To do that, we can let the holder know that we want to handle related events. To do this, we call surfaceHolderInstance.addCallback(viewInstance). But one more catch – the object you pass to this method must implement an interface defined as SurfaceHolder.Callback. So our class definition starts out as:

public class AnimView extends SurfaceView implements SurfaceHolder.Callback {

When you do that, you’ll be informed that you are not implenting the required methods of that interface. Use a quick fix to add them. With all that done, you should have the following:

Threading

Now we can start animating. In animation, you need generally have some kind of model of what you are animating, with some kind of rules on how that model changes. you need to update the model, and then render that model to the display, then update the model again, render again, and so on.

If you are used to animating in Flash you’re familiar with doing this via enterFrame, or perhaps with timers. Timers are also used in JavaScript animation. In Android though, we generally use threads.

Threads can be a bit scary as they are a bit more complex than a simple timer. If you’re not familiar with threads, the concept is just that you are starting another process that runs independently from the main process. This is useful for operations that might take a long time or will not return immediately. The new thread does its own thing in its own time frame, and the main process of your app continues to do what it needs to do, remaining responsive, etc.

The scary part of threads is that they run separately, but are able to access the same variables and objects in a non-synchronized way. Thus, one thread might be performing some procedure on a given object, and right in the middle of tht procedure, the other thread might step in and change the state of that object or even delete it. So you have to take some extra steps to guard against these types of situations.

Our view will use a separate thread to perform its animation. We will create and start the thread running in the surfaceCreated method, and we will stop the thread in the surfaceDestroyed method. There are a number of different ways to use threads. The way we’ll do it is to subclass the Thread class and put the custom functionality in that class.

Here’s the start of our custom thread class:

In order to draw to a canvas, we’ll need the surface holder to get the canvas from, so we’ll pass that in in the constructor and save it. We’ll also need a variable that will indicate whether or not the thread is currently running and a way to set that.

When we create an instance of this thread class and call start() on it, its run method will be executed in a separate process. We’ll actually use a while loop to do our animation. This may seem odd if you’re coming from the Flash or JavaScript world, where in infinite while loop would just lock things up. But because this is in a separate thread, it works out fine.

The pseudocode for what we will do is like this:

This will just run forever. Well, until we set running to false anyway. As you might have guessed, we’ll create and start the thread in the surfaceCreated method and we’ll set running to false in the surfaceDestroyed method. There’s a few more details to it, but we’ll get there eventually.

Locking and Unlocking

To get a canvas from a surface holder, we actually call holder.lockCanvas(). This prevents anything from happening to the canvas while we are using it. When we are done with our drawing, we call holder.unlockCanvasAndPost(canvas), passing in the canvas instance we just drew to. This frees it up and displays what was just drawn.

Here is the final code with some actual animation going on:

Here you can see we declare the canvas variable, then we enter a try block where we get the canvas and do the drawing. This allows us to unlock the canvas in a finally block, so that even if an exception is thrown while drawing, we won’t leave the canvas in locked state.

Note that the drawing is done in a synchronized block. This puts a lock on the holder so that nothing else can change it from another thread while we are using it. In this block we set the background to black and draw a white circle. The x value will be incremented on each loop, moving the circle across the screen.

Starting and stopping the thread

All we have to do now is create, start, and stop this thread. We’ve already said that we’ll do that in surfaceCreated and surfaceDestroyed methods. So let’s see what this looks like. First the created:

Simple enough. We create the thread, passing in the suface holder, set running to true, and start it. This will wind up executing the run method, which will run that for loop in a separate process.

The destroyed method is a bit more complex:

First of all, we set running to false. This will allow the while loop in the run method to exit. But since that’s happening in another thread, we don’t know exactly when that’s going to happen. So we want to make sure that it’s really fully complete before we leave here. We do that with the join method of the thread. That will cause execution to stop and wait for that thread to end. However, this will sometimes result in an InterruptedException. So we throw that whole thing in a try/catch statement and keep retrying it until the join finally successfully returns. Here’s the final AnimView class:

, , , ,