Raguel

Raguel

(2 comments, 2 posts)

This user hasn't shared any profile information

Home page: http://www.doublecluepon.com

Posts by Raguel
Raguel-headcon

The definitive guide to why executable evironments are never “dead”

0
By: Azrael & Raguel

There has been much hay made of the recent announcement over Windows 8 Metro not having support for all plugins. While this is an interesting move by Microsoft, it’s not completely unexpected. Like many they are enamored over the promise of HTML5, and what it can do. However, this has re-ignited the “Flash is dead” idiocy across the internet.

Yes, it’s idiocy. Hand-waving freak-outery aside… I’ll go one further: proclaiming an executable environment dead instantly shows to the world that you do not understand the technical issues of the debate, in which case you should really stop posting. Or, to put it in the way Raguel put it: Flash has evolved, but the arguments have not. Talking about Market Share, native support for Execution Environments… irrelevant. Especially when it comes to the PC.

Why is this lunacy? Because, for the most part, true native support for outside code interpretation has always been something that is an add-on. The argument that “Flash is dead” conveniently ignores the fact that Flash is no longer just a program for making banner ads. It shows a complete and utter lack of understanding of how Flash has evolved, along with the Flex environment, AIR, and ActionScript 3.

To understand it, you need to understand the underlying components of what makes Flash, Flash:

  • ActionScript 3 is an ECMAScript-based, compiled, Object-Oriented programming language. It’s syntactically very similar to its sibling JavaScript (another ECMAScript-based language).
  • ActionScript is compiled into bytecode into a SWF file.
  • The ActionScript Virtual Machine is the interpreter/run-time environment for compiled ActionScript programs.
  • Adobe AIR, the Adobe Integrated Run-time, provides support for JavaScript, ActionScript, MXML, and HTML to be used to build Rich Internet Applications which can run in a browser or as standalone desktop applications.

Now, let’s take a look at Java:

  • Java is a compiled, Object-Oriented programming language. Syntactically, it’s very similar to its predecessors, C and C++, and even moreso to its sibling C#.
  • Java is compiled into bytecode, in the form of a JAR file.
  • The Java Virtual Machine (JVM) is the interpreter/run-time environment for compiled Java programs.

The similarities do not end there either. Here are some fun quotes about Java from 1998 (bold emphasis is ours):

JAVA truly is the great equalizing software. It has reduced all computers to mediocrity and buggyness.

–Anonymous at NASA

There are a few things that are in the way of Java becoming a well-established platform for applications. IMO, one obstacle is the CLASSPATH stuff. Another is the fact that applications are not as easy to install as native ones. Performance is a consideration too, of course.

–Jose H. Solorzano on the advanced-java mailing list

Standards are, among other things, supposed to provide islands of stability with a minimum life of five years. Currently Sun seems to be shipping new (not entirely compatible) releases of Java every year. To my mind that is clear evidence that the product is not yet stable enough to be standardised.

–Francis Glassborow on the SC22JSG mailing list

Sure, Java’s great for distributed enterprise applications, and maybe even for embedded systems, but it simply hasn’t lived up to its promise of “write once, run everywhere.” And on the Web, even the smallest Java applets drive surfers crazy as they wait for their Java Virtual Machines to load. That’s why many people turn off Java in their browsers. They’re simply unwilling to wait for something that isn’t that interesting in the first place. And let’s face it, the vast majority of Java applets on the Web are a drag. Most Java applets don’t do anything but look cool.

–Fredric Paul

Java on the client doesn’t work, and we at Netscape have done an about turn on client-side Java in recent months. But on the server side, Java is taking off quite quickly.

–Marc Andreesen

So Java applets crash my browser, and the Java technology that’s supposed to be cross-platform plainly isn’t. A good portion of the blame for this surely belongs to Sun; the company has declined to release its hold on Java to an independent standards body, and Sun and Apple have been extremely late in delivering this so-called cross-platform technology to Mac users.If this is what Java is all about, I’ll take decaf.

–Joanna Perlstein

And on and on and on… But wait! Java is still in use practically everywhere. Java didn’t die then, and it’s certainly not dead now. Proclamations of it’s demise were, at the time, greatly exaggerated. Even if you count Microsoft’s attempts to Embrace, Extend and Extinguish Java. Java, in the mid to late 90′s was just as — if not more than — reviled as Flash is now. It was proclaimed dead many times. It was slow, buggy, inhibited performance of the browser, crashed browsers (and machines). Yet here we are today. Java is still around. Contrary to the worries of the pundits, it’s thriving.

Starting to see where this is going?

Now, let’s look at some other examples.

  • Perl is a high-level, general-purpose, interpreted, dynamic programming language.
  • Perl requires an interpreter, which is not included with Windows, in order to run Perl scripts. This must be installed by the user.
  • It is also dead. Though the Perl is not dead campaign is gaining momentum.

How about another?

  • Python is a high level, general-purpose multiple paradigm programming language.
  • Python requires an interpreter which is not included with Windows, and must be installed by the user.

When you begin to understand the technology, you start to realize Flash is not just about the Flash IDE, creating easy SWF’s with tweened graphics for a banner ad, or a menu bar on a website. If you don’t understand by now that Flash’s core ActionScript is an Object Oriented language executable environment then you do not have the technical knowledge required to make a judgement on technology.

Alternative executable environments are a staple of modern computing. They almost never ever die. Proclaiming that one is dead is akin to announcing to the world, “I’m an idiot who does not understand technology” while wearing nothing but clown shoes and chaps. Think we’re wrong about this?

Try this on for size:

  • While the original DOS was an operating system (and we use that term loosely) at the core these days, it’s a code execution environment. Good Old Games, Steam and others bundle DOS Box to run legacy games. While DOS is no longer supported by Microsoft, it still lives on to this day.
  • Z80 Environments, which have a long and storied history, live on in the MAME Project. MAME is the Multi Arcade Machine Emulator. Like DOSBox, it’s a legacy code execution environment.
  • Many other computing environments have been virtualized and have homebrew communities, like Atari 2600, NES, and others.

These are examples of how environments to execute programs never really go away. But let’s get back to this argument over how a lack of native support somehow is a death knell for these environments. People who make absolutist arguments about technology are the ones who typically have no grasp of technology beyond their own limited scope. They suffer from a very real tunnel vision. There are dozens, if not hundreds of sites offering cheap Apache/PHP hosting. Does that mean Perl is dead? How about the Microsoft IIS server? Apache is still in the lead. Especially when you throw in Tomcat. Does that mean IIS is an ailing and dying duck? No.

A lot of the arguments made about Flash these days (Sadly, by many an Apple fan, and others who should know better) are the same as the ones that were being shouted out back in the 90s when Gil Amelio was at the helm at Apple. Apple’s dead. They’re not relevant, they aren’t used in business, Microsoft won. Without vendor and software support, Apple is doomed. Yet, look at where they are today. (Disclosure Note: Azrael was once a devout Mac head, who spent many years in the wilderness with a PowerBook, and other assorted hardware, and still has his Newton. Raguel laughed when Apple died and now lives on current Apple laptops, and owns a half-dozen other devices in the Apple ecosystem.)

The problem with absolutist arguments when you work in technology is this: they preclude you from understanding the most basic rule in technology, which is use the right tool for the job you have before you. It also keeps you from seeing something else: technology evolves and matures.

When you start talking about a lack of native support in this context…you already lose the argument. We have news for you: with every Windows machine any of us have ever owned, We have had to install the Sun (now Oracle) branded Java JRE/JVM to run the things we want/need. You’re often auto-prompted to do so. We have installed the AIR framework to run AIR Apps, prompted to do so when the things needed to run the apps are not there. Like TweetDeck (which is a standalone app, btw)…which have no bearing on browsing. Oh, and we install Chrome, Opera and FireFox. With Chrome or Firefox being often being selected as the default browser. We rarely, if ever use IE. So, native support is not an issue here when it comes to non native code execution environments. It does not matter what Microsoft does with Metro on Windows 8. The landscape is not changing much, if at all when it comes to running the things you want to run.

Flash/Flex/ActionScript/AIR are far from dead. They will continue on, in spite of the continued pining of people who have not one jot of a clue.

With all that said, there are a few people who have pointed out the flip side to the coin. Seantron makes a very good point: Flash developers should be doing more to “get out of the box” that is the Browser. The “What Games Are” blog asked, “So where does this leave browser based games? Has Microsoft just announced their doom?” rather than just proclaimed doom and gloom. They also pointed out, this affects all browser games that are not HTML 5. While Flash is a most favored whipping boy…where does the no plugin policy leave Unity? By some people’s logic… Unity must therefore be dead. But, hey… Unity is a development environment, it has a code execution environment too. It uses a plugin! It’s not going to die anytime soon, and neither will Flash/Flex/AIR.

In closing, remember… absolutist statements when dealing with technology are often the telltale sign of someone who does not, in fact, understand technology. While some things may be more immediately apparent than others, remember this: at least once a day, your browser receives an answer from Perl, and PHP. You’ve received the results of Python in your time. You use Java more than you’re probably aware of. Every time you hit Armor Games, you’re using Flash. Oh, and for what it’s worth: most Flash games these days are not created in Flash CS. They are created using the Flex environment, or other open environments, or with free compilers outside of Adobe’s sphere.

There are a lot of people who think minimalist websites laden with quasi intellectual prose somehow stand as an authority to all that is. In our experience, it’s these types that talk a great deal, but say nothing. They’re willing to tell you the cost of everything, but omit the value of anything that stands in the way of their meager, tactless (and often factless) argument.

Despite Microsoft’s positioning, and in spite of the wishes of many, Flash, and its various components such as Flex, AIR, etc are going to be around for a long time to come. ActionScript and AIR are maturing, and getting better. So is Python, and Perl. (we use all three here). We apply the tech that makes sense for what we do. We do not make sweeping, absolute declarative statements when it comes to technology. Nobody should. When you see people do this, remember…it’s a sign they do not understand what it is they are talking about.

Ja Mata!

EDIT: It seems Microsoft has indeed clarified this positon: “Open distribution: retail stores, web, private networks, individual sharing, and so on” will be allowed, Microsoft says. Metro apps, on the other hand, will be “Distributed through the Windows Store. Apps must pass certification so that users download and try apps with confidence in their safety and privacy. Side-loading is available for enterprises and developers.”

Which basically nulls the “flash is dead” debate. The debate over whether or not a company should have the right to control what you may, or may not install on a mobile device is a separate one, and is still raging hard. 

Raguel-headcon

Building StoryTeller: Using Make to Compile Flex Projects

0

I’ve been a Unix guy since I got my first custom computer. I am a king of the command-line, a die hard text-only advocate. I think in Vim and Bash, so it’s only natural that I use the command-line Flex SDK to build StoryTeller and SwfConduit.

However, the Flex SDK doesn’t have the convenience of the other Flex build systems. To build a SWF is one command (mxmlc). To build an AIR app from a SWF and an app.xml document is another command (adt). To test the AIR SWF is another command (adl). These commands must share similar configuration options, so it’s only natural to want some kind of script or program to handle that for
you.

GNU Make is a general build system. Given a set of “targets” (built files), a list of prerequisites for that target, and a set of instructions, Make will perform the necessary steps to build your software.

Say you have yourapp.mxml, and you want to build yourapp.air manually. You would have to perform three steps:

  1. Generate yourapp.swf from yourapp.mxml using amxmlc (for an AIR app)
    amxmlc -sp+=. -l+=. -strict=true -debug=true -o yourapp.swf yourapp.mxml
  2. Ensure a yourapp.pfx certificate exists to sign yourapp.air
    adt -certificate -cn yourcompany.com -ou YourApp -o "Your Company" -c "US" 2048-RSA yourapp.pfx yourpass
  3. Generate yourapp.air from yourapp-app.xml, yourapp.swf, and yourapp.pfx
    adt -package -storetype pkcs12 -keystore yourapp.pfx -storepass yourpass yourapp-app.xml yourapp.swf

To do this with a Makefile, we would do the following:

yourapp.air : yourapp.swf yourapp.pfx
	adt -package -storetype pkcs12 -keystore yourapp.pfx -storepass yourpass yourapp-app.xml yourapp.swf
yourapp.swf :
	amxmlc -sp+=. -l+=. -strict=true -debug=true -o yourapp.swf yourapp.mxml
yourapp.pfx :
	adt -certificate -cn yourcompany.com -ou YourApp -o "Your Company" -c "US" 2048-RSA yourapp.pfx yourpass

Once we have this saved as “Makefile” in the same directory as our source, we can simply type make at a command-line and it will create “yourapp.air”.

There are three sections to this Makefile, called “targets”. Each target is a different file, either yourapp.air, yourapp.swf, or yourapp.pfx. Since yourapp.air is the first target, it is the default target, so typing “make” with no arguments will build yourapp.air.

After the target file comes a colon and then an optional space-separated list of prerequisites, which are other targets that must be completed before the current target can build. So, in order to build “yourapp.air”, we must have already built “yourapp.swf” and “yourapp.pfx”.

After the prerequisites list we put a newline, then a tab, then the command that should be run to build the target. For example, to build “yourapp.swf”, we invoke the amxmlc command with some options.

Using Variables

Like most Unix tools, Make has plenty of flexibility for writing consise, easy-to-maintain Makefiles. The first thing we should probably do is use variables instead of copying the same strings in multiple places. This will allow us to simply re-use the same Makefile for multiple projects by changing a few configuration values.

You should put variable declarations at the top of a Makefile. Variables are declared simply with VARNAME = VALUE, like so:

AIR = yourapp.air
SWF = yourapp.swf
CERT = yourapp.pfx
MXML = yourapp.mxml

Once we’ve declared the variables, we can use them as either targets or substitutions in our commands using $(VARNAME).

$(AIR) : $(SWF) $(CERT)
	adt -package -storetype pkcs12 -keystore $(CERT) -storepass yourpass yourapp-app.xml $(SWF)
$(SWF) :
	amxmlc -sp+=. -l+=. -strict=true -debug=true -o $(SWF) $(MXML)
$(CERT) :
	adt -certificate -cn yourcompany.com -ou YourApp -o "Your Company" -c "US" 2048-RSA $(CERT) yourpass

While we’re at it, we should probably replace most of our commands with variables. Doing this will make our commands re-usable in other Makefiles.

AIR = yourapp.air
SWF = yourapp.swf
SWFOPTS = -sp+=. -l+=. -strict=true -debug=true
CERT = yourapp.pfx
CERTINFO = -cn yourcompany.com -ou YourApp -o "Your Company" -c "US"
CERTTYPE = 2048-RSA
CERTPASS = yourpass
MXML = yourapp.mxml
APPXML = yourapp-app.xml

$(AIR) : $(SWF) $(CERT)
	adt -package -storetype pkcs12 -keystore $(CERT) -storepass $(CERTPASS) $(APPXML) $(SWF)
$(SWF) :
	amxmlc -o $(SWFOPTS) $(SWF) $(MXML)
$(CERT) :
	adt -certificate $(CERTINFO) $(CERTTYPE) $(CERT) $(CERTPASS)

Now we can split our Makefile into two parts, the first part setting up the variables for this project, the second part included from a common directory.

# Makefile
AIR = yourapp.air
SWF = yourapp.swf
SWFOPTS = -sp+=. -l+=. -strict=true -debug=true
CERT = yourapp.pfx
CERTINFO = -cn yourcompany.com -ou YourApp -o "Your Company" -c "US"
CERTTYPE = 2048-RSA
CERTPASS = yourpass
MXML = yourapp.mxml
APPXML = yourapp-app.xml
include Makefile.flex
# Makefile.flex
$(AIR) : $(SWF) $(CERT)
	adt -package -storetype pkcs12 -keystore $(CERT) -storepass $(CERTPASS) $(APPXML) $(SWF)
$(SWF) :
	amxmlc -o $(SWFOPTS) $(SWF) $(MXML)
$(CERT) :
	adt -certificate $(CERTINFO) $(CERTTYPE) $(CERT) $(CERTPASS)

Now, Makefile.flex can be symlinked to multiple projects, since it doesn’t
have to change at all!

A Challenger Appears: Make on Windows!

I said I’m a Unix guy, but unfortunately I’ve had to switch to a Windows 7 laptop for a couple months now. Luckily for me, Windows has a Linux environment available called Cygwin! Unluckily, getting Cygwin to work with
the Windows Flex SDK, Java for Windows, and Ant for Windows took some hacking.

I installed Flex, Java, and Ant from their vendors using the Windows versions. I installed Cygwin making sure to include GNU Make. However, using the same Makefile I used on my OSX laptop ran into some puzzling errors: Unable to access jarfile /cygdrive/c/flex/lib/mxmlc.jar when that file definitely exists in the Cygwin environment.

It turns out that using the Bash scripts from the Flex SDK for Windows doesn’t work in the Cygwin environment, mainly because Cygwin has to map C:\flex\lib to a proper Cygwin Unix-like directory path, /cygdrive/c/flex/lib. So to make the Flex SDK work under Cygwin, we have to make sure to use the Windows-specific batch files and executables so that all the paths are found.

To make this simple, we will replace our commands (amxmlc and adt) with variables, then use an optional include file to override those variables on our Windows machines. If the optional include file doesn’t exist, we’re on a Unix system and everything works. If the optional file does exist, we’re on a Windows system and everything works.

In our Makefile.flex, we’ll change our commands to use variables, like so.

# Makefile.flex
ADT = adt
AMXMLC = amxmlc

$(AIR) : $(SWF) $(CERT)
	$(ADT) -package -storetype pkcs12 -keystore $(CERT) -storepass $(CERTPASS) $(APPXML) $(SWF)
$(SWF) :
	$(AMXMLC) -o $(SWFOPTS) $(SWF) $(MXML)
$(CERT) :
	$(ADT) -certificate $(CERTINFO) $(CERTTYPE) $(CERT) $(CERTPASS)

Now we’ll add an optional include for a Makefile.cygwin. The – in front of include means “ignore any errors, like if the file doesn’t exist.”

# Makefile.flex
ADT = adt
AMXMLC = amxmlc
-include Makefile.cygwin

$(AIR) : $(SWF) $(CERT)
	$(ADT) -package -storetype pkcs12 -keystore $(CERT) -storepass $(CERTPASS) $(APPXML) $(SWF)
$(SWF) :
	$(AMXMLC) -o $(SWFOPTS) $(SWF) $(MXML)
$(CERT) :
	$(ADT) -certificate $(CERTINFO) $(CERTTYPE) $(CERT) $(CERTPASS)

Finally, if we’re on a Windows system, we’ll add our Makefile.cygwin:

# Makefile.cygwin
ADT = adt.bat
AMXMLC = amxmlc.bat

Now Cygwin will use the Windows-specific batch files from the Flex SDK instead of the Unix-specific shell scripts, but only on Windows.

I’ve only recently started using Make to build projects, and it is an incredibly powerful tool.

If you have any questions about using Make with your own Flex projects, or if you have ideas for how to improve these Makefiles, let me know in the Emerald Kingdom Developer Forums.

For more information about GNU Make, see http://www.gnu.org/software/make/

Creating the project

SwfConduit Tutorial: A Simple Chat Server

0

NOTE: The permanent version of this tutorial, updated as SwfConduit develops, is located at our project wiki: https://github.com/doublecluepon/SwfConduit/wiki/A-simple-chat-server. You can ask questions about this tutorial in our SwfConduit Forum.

As part of the first stable release of SwfConduit, Double Cluepon’s free, open-source flash socket server written in Python, I’ve prepared a simple example to show how to get started writing your own servers.

In this example, we’ll create a very simple chat room. Users will join the room by launching a swf file and then they can talk with all the other users in the room.

Installing SwfConduit

Server Requirements

First, we will need to install the server’s requirements:

  • Python 2.6+ (Python 3 will not work)
  • Twisted
  • PyAMF 0.6

Twisted and PyAMF can both be installed using Python’s easy_install:

$ sudo easy_install twisted   
$ sudo easy_install pyamf

Finally, we can get the latest SwfConduit from https://github.com/doublecluepon/SwfConduit/tarball/master

Client Requirements

Using Flash Builder

If you’re using Flash Builder, you should have everything you need to create SwfConduit projects.

Using any editor

If you want to use another editor, you can download the free Adobe Flex 4 SDK from http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4. Once you’ve downloaded the Flex SDK, you’ll want to make sure you can run “mxmlc” from your terminal.

Running the Example

Start the server

Start the chat server by invoking twistd from a terminal:

$ cd examples/chat
$ sudo twistd -ny chat.py

A bunch of text should scroll onto the screen, resembling the below block

2011-05-28 22:42:31-0500 [-] Log opened.
2011-05-28 22:42:31-0500 [-] twistd 11.0.0 (...) starting up.
2011-05-28 22:42:31-0500 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2011-05-28 22:42:31-0500 [-] swfconduit.socketpolicy.SocketPolicyFactory starting on 843
2011-05-28 22:42:31-0500 [-] Starting factory <swfconduit.socketpolicy.SocketPolicyFactory instance at 0x10196eb48>
2011-05-28 22:42:31-0500 [-] swfconduit.server.Server starting on 8000
2011-05-28 22:42:31-0500 [-] Starting factory <swfconduit.server.Server instance at 0x10196eab8>

If there are no error messages, the server is running. Leave the terminal open while you start the client.

Start the client

Using Flash Builder

First, we need to create a new Flex Project. We’ll call our new project Chat. Give it an Application Type of “Web” and click Finish.

Creating the project

Next, we need to import the swfconduit libraries. Right-click on the “libs” folder in the Package Explorer and choose “Import…” from the pop-up menu. In the dialog box, open the General folder, choose “File System” and click Next. Choose the swfconduit/flex folder and make sure it’s checked in the box on the left. Then click Finish to import the files.

Click the Import... menu item

Choose "File System"

Select the swfconduit directory

Files are imported

Finally, we need to import the files from the swfconduit/examples/chat folder. We follow the same procedure as we did when we imported the swfconduit libraries. Right-click on the “src” folder in the Package Explorer and choose Import… from the pop-up menu. In the dialog box, open the General folder, choose “File System” and click Next. Browse to the swfconduit/examples/chat folder, make sure it’s checked in the box on the left, and click Finish to import the files.

Importing the Chat source

Select "File System"

Select the chat directory

Chat directory is imported

Now, we can open our chat.mxml file and Run it. Your browser will open and the chat window will appear. If the server is running (it should be), you’ll be able to chat.

Open Chat.mxml

Running Chat in Chrome

 

Using any editor

Compile the chat.swf by invoking mxmlc:

$ cd examples/chat
$ mxmlc -l+=../../flex chat.mxml

Then, open the chat.swf file and try it out.

You can use /nick NEW_NICK to change your nickname, and opening the chat.swf multiple times will allow you to talk to yourself without danger of people thinking you’re weird or sending you to therapy.

Creating the Example

The Server

The SwfConduit server handles messages using Event classes. The client sends events to the server, and the server sends events to the client. All the communication is asynchronous, so the server doesn’t have to wait for the client to make a request.

So, the first thing we need to do to build a chat server is create the ChatEvent class. First we import the swfconduit Event base class and create our subclass.

# Create our event class
from swfconduit.event import Event
class ChatEvent( Event ):

Next, we add the properties of the event. ChatEvent needs a nickname of whosent the message, and the actual text of the message.

    # The nickname of the user sending the event
    nickname = ""
    # The message
    text = ""

Finally, we need to describe what to do when the server recieves a ChatEvent. SwfConduit events have a fire() function that gets called when the server recieves it. fire() recieves the swfconduit Server object for the current server, and the swfconduit Session object which is the session that sent the event.

In our fire() function, we’re going to loop over all the other connections to the server and forward the event to them.

    def fire( self, server, session ):
        # We recieved a chat event, send it to every other person
        for session_id in server.sessions:
            s = server.sessions[session_id]
            if (s is not session):
                s.sendEvent( self )

Once we’ve built our event class, we need to register the class with PyAMF in order for it to be correctly serialized. We’ll also need to register the ChatEvent class we create on the client, later. The server and client will both share the ID string “swfconduit.chat.ChatEvent” to know what they’re serializing.

# Register our ChatEvent class. the first argument is the same as the
# registerClassAlias string in the client
import pyamf
pyamf.register_class( ChatEvent, "swfconduit.chat.ChatEvent" )

With the event class created and registered, we can create our server using the swfconduit Server class. Our server will use the TCP protocol on port 8000, so we’ll pass that into the server’s configuration dict.

# Create the SwfConduit server
from swfconduit.server import Server
server = Server({ "proto" : "tcp", "port" : 8000 })

Now, we’ll load up the application that twistd will execute for us using the swfconduit Loader. The Loader will also handle the socket-policy.xml file for us, which is placed in the same directory as our server program.

# Load and run SwfConduit
from swfconduit.loader import Loader
loader = Loader()
loader.servers.append( server );
application = loader.get_application()

That’s it! We can now run our server:

$ twistd -ny chat.py

The Client

Now that we have our server, we need something to connect to it. We’ll create a simple MXML component that will take input from the user and display the incoming chat messages.

First, like our server, we need a ChatEvent. On the client, swfconduit events extend the swfconduit.Event class.

package swfconduit.chat {
    import swfconduit.Event;
    public class ChatEvent extends swfconduit.Event {

We make the same public attributes as the server’s ChatEvent. If the two disagree, the flash client will warn you about the attributes it can’t find.

        // The person who sent the event
        public var nickname:String;
        // The message being sent/recieved
        public var text:String;

Finally, we’ll make a constructor that makes it easier to create ChatEvent objects. If we override the constructor for an Event, we must provide defaults. When the Event is sent by the server to the client, Flash will use the constructor, but will not pass any arguments to it.

        public function ChatEvent( nickname:String="", text:String="" ) {
            this.nickname = nickname;
            this.text = text; 
        }
    }
}

And that’s all our ChatEvent needs to do. Notice how the client doesn’t do any handling of the Event. Unlike the server, the client’s handling of the event is done using event listeners.

But before we can listen for ChatEvents, we have to build a form. We’ll create a Spark Application that has an area for the chat, an input field to type into, and a label for the user’s current nickname.

<?xml version="1.0" encoding="utf-8"?>
<s:Application width="400" height="300" 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
>
    <s:layout><s:VerticalLayout /></s:layout>
    <s:RichEditableText editable="false" id="chatbox" width="100%" height="250">
        <s:text>*** Type /nick NEW_NAME to change your nickname</s:text>
    </s:RichEditableText>
    <s:TextInput id="input" width="100%" height="25" />
    <s:Label text="You are {nickname}" height="20" />
</s:Application>

We’re using RichEditableText so that we get scrolling automatically, but we’resetting editable to false because users should be typing into the TextInputbelow it. Finally, a Label with text bound to the “nickname” field (that wehave yet to create).

So now that we have our form, we’ll add our script. First we need to import the swfconduit libraries and our ChatEvent. Since we’re also going to be working with keyboard events (pressing Enter to send text), we’ll import the flash KeyboardEvent class.

    <fx:Script><![CDATA[
        import swfconduit.Socket;
        import swfconduit.chat.ChatEvent;
        import flash.events.KeyboardEvent;

Now, we'll need to keep some data around, like the hostname and port to connect to, the connected socket to the swfconduit server, and the user's nickname.

        public var hostname:String = "localhost";
        public var port:uint = 8000;
        public var socket:swfconduit.Socket;
        [Bindable]
        public var nickname:String;

Next, we’ll need to connect to the server. We’ll create an init function that will register our classes and connect to the server.

        public function init():void {
            // Register our event class
            registerClassAlias( "swfconduit.chat.ChatEvent", ChatEvent );
            // Connect to the server
            socket = new swfconduit.Socket( hostname, port );
        }

We’ll need to call our init() function when our application is completed, so add ‘applicationComplete=”init()”‘ to our <s:Application> tag.

<s:Application width="400" height="300" applicationComplete="init()"

Next, we need to handle incoming ChatEvent messages. As they come in, we need to add the text to our chatbox text area.

        public function handleChat(event:ChatEvent):void {
            chatbox.appendText( "\n" + event.nickname + ": " + event.text );
        }

We add our event listener in our init() function, after we create our socket.

        public function init():void {
            // Register our event class
            registerClassAlias( "swfconduit.chat.ChatEvent", ChatEvent );

            // Connect to the server
            socket = new swfconduit.Socket( hostname, port );
            socket.addEventListener( "ChatEvent", handleChat );
        }

Now, as ChatEvents come in, they’ll be added to the chatbox. Finally, we need to send out ChatEvents of our own. We’ll add a handler for the Enter key so that it sends out the message.

        public function sendChat(event:KeyboardEvent):void {
            if ( event.keyCode == 13 ) {

We also want to allow users to change their nickname, so we’ll do that first.

                // Let the user change their nickname using /nick NewName
                if ( input.text.match('^/nick') ) {
                    nickname = input.text.substr(6); // Everything after "/nick "
                }

If they’re not changing their nickname, they’re trying to talk, so we’ll create a new ChatEvent object and send it out over the socket. We also add their text to the chatbox, because we won’t get our ChatEvent back.

                else {
                    socket.writeEvent( new ChatEvent( nickname, input.text ) );
                    chatbox.appendText( "\n" + nickname + "> " + input.text );
                }

Last, we clear out the input so the user can chat more.

                input.text = "";
            }
        }

Again, we add the listener in our init() function.

        public function init():void {
            // Register our event class
            registerClassAlias( "swfconduit.chat.ChatEvent", ChatEvent );

            // Connect to the server
            socket = new swfconduit.Socket( hostname, port );
            socket.addEventListener( "ChatEvent", handleChat );

            // When enter is pressed, send the event
            input.addEventListener( KeyboardEvent.KEY_UP, sendChat );
        }

And that’s all the script we need.

    ]]></fx:Script>

Now we can compile our swf file and try it out.

$ mxmlc -l+=../../flex chat.mxml
$ open chat.swf

That covers the basics of how to use the SwfConduit server.

How To Do Anything

Server Side

At its core, SwfConduit is a very thin wrapper around Twisted and PyAMF. The swfconduit Server class is a Twisted Factory, the swfconduit Session class is a Twisted Protocol that handles encoding and decoding the AMF. You can extend the Server and Session classes to track more data, such as database connections and player information.

But the grunt work is really done in your Event classes. By registering your event class with pyamf.register_class(), any event that comes in will have its fire() method called. Your events can log a user in, retrieve and update objects from the database, or just pass events along to other people (like theChatEvent did).

Client Side

SwfConduit is merely the transport and dispatch layer. Your Event classes just send and recieve data, all the real work is done by your event listeners. By passing the SwfConduit socket around, you can build ORMs, game clients, editors, and anything else you want.

The Future

SwfConduit is the beginning of a platform for multiplayer game development in Flash. As more pieces are developed, we’ll release them as SwfConduit plugins. Simple things like an ORM based on SQLAlchemy, users and profiles, or a chat system that can be quickly integrated with your own projects.

SwfConduit will always be free and open source. Game development should be more accessible to beginning programmers, and SwfConduit will be one of our tools to make that happen.

Raguel's RSS Feed
Go to Top