Building a Flash Chat Socket Server with Stackless Python

Post to Twitter

When most people decide to build a socket server for their Flash/Flex projects they usually turn toward using Java since there are many excellent ways to go about building on some great frameworks. Today however I’ll quickly build a socket server using Stackless Python and communicate to Flash CS4.

The first thing you will need to do is install Stackless Python – make sure to follow the instructions carefully and test it out to ensure you have it working before proceeding. I did the install on Windows 7 and used the precompiled binaries provided for Python 2.6.3.

In the Stackless Python wiki examples I found a sample application for a chat server. I took this sample code and modified to work with Flash CS4:

#
# An example that uses stacklesssocket to provide a chat like application.
# The users connect via telnet to the IP:port of the server and type in any
# text and all users connected receives it.
# The server identifies an special character to close the connection and handle
# the connected client list.
#
# The example is based on mud.py but uses the standard dispatcher creating a
# tasklet for each connectedclient.
#
# Author: Carlos Eduardo de Paula <carlosedp@gmail.com>
#
# This code was written to serve as an example of Stackless Python usage.
# Feel free to email me with any questions, comments, or suggestions for
# improvement.
#
# But a better place to discuss Stackless Python related matters is the
# mailing list:
#
#   http://www.tismer.com/mailman/listinfo/stackless
#
#
# *** Code modified by Chad Lung to work with Flash CS4 ***
# Original code can be found here:
# http://stacklessexamples.googlecode.com/svn/trunk/examples/networking/chatServer.py
#

import sys, time
import stackless

import stacklesssocket
#sys.modules["socket"] = stacklesssocket
stacklesssocket.install()
import socket

class Server(object):
    def __init__(self, conn):
        self.clients = {}
        # Create an INET, STREAMing socket
        self.serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # Bind the socket to an addres, and a port
        self.serversocket.bind(conn)
        # Become a server socket
        self.serversocket.listen(5)
        stackless.tasklet(self.acceptConn)()

    def acceptConn(self):
        while self.serversocket.accept:
            # Accept connections from outside
            (clientsocket, address) = self.serversocket.accept()
            # Now do something with the clientsocket
            # In this case, each client is managed in a tasklet
            stackless.tasklet(self.manageSocket)(clientsocket, address)
            stackless.schedule()

    def manageSocket(self, clientsocket, address):
        # Record the client data in a dict
        self.clients[clientsocket] = address
        print "Client %s:%s connected..." % (address[0],address[1])
        # For each send we expect the socket returns 1, if its 0 an error ocurred
        if not clientsocket.send('Connection OK Type "quit" to quit.\0'):
            clientsocket.close()
            return
        data = ''
        while clientsocket.connect:
            data += clientsocket.recv(4096)

            print data

            if data == '':
                break
            # If we detect a \0 filter the event
            if '\0' in data:
                if data == '\0':
                    if not clientsocket.send("Empty string sent\0"):
                        break
                elif data == 'quit\0':
                    # If the user sends a q!, close the connection and remove from list
                    print "Closed connection for %s:%s\0" % (address[0],address[1])
                    del self.clients[clientsocket]
                    break
                elif data == 'look\0':
                    # Show the connected clients
                    clientsocket.send("There are %d users connected:\0" % len(self.clients))
                    clientsocket.send("Name\tHost\t\tPort\0")
                    clientsocket.send("-" * 40 +"\0")
                    for clientIP, clientPort in self.clients.itervalues():
                        clientsocket.send("Unknown\t"+ str(clientIP) +"\t"+ str(clientPort) +"\0")
                else:
                    # Send the message to all connected clients
                    for client in self.clients:
                        if client is clientsocket:
                            if not client.send('\rYou said: %s\0' % data):
                                break
                        else:
                            if not client.send('\rClient %s said: %s\0' % (address,data)):
                                break
                data = ''
            stackless.schedule()
        clientsocket.close()

if __name__ == "__main__":
    host = "127.0.0.1"
    port = 80
    print "Starting up server on IP:port %s:%s" % (host, port)
    s = Server((host,port))
    stackless.run()

I did minimal changes to the original code if you care to do a comparison. Make sure to also download this file (stacklesssocket.py) and put it in the same directory as the file above.

In Flash CS4 create a new project and layout the interface like this:

Basic Chat Interface

So nothing special there. You can download the Flash CS4 project files here: BasicChat

All that’s left now is the ActionScript code used to talk to our socket server:

var xmlSocket:XMLSocket = new XMLSocket();
xmlSocket.connect("127.0.0.1", 80);

xmlSocket.addEventListener(DataEvent.DATA, onIncomingData);
send_btn.addEventListener(MouseEvent.CLICK, clickHandler);
disconnect_btn.addEventListener(MouseEvent.CLICK, disconnectHandler);

function clickHandler(event:MouseEvent):void
{
	xmlSocket.send(input_txt.text);
	input_txt.text = "";
}

function disconnectHandler(event:MouseEvent):void
{
	xmlSocket.send("quit");
	// You could also just close the socket like this
	//xmlSocket.close();
	send_btn.enabled = false;
}

function onIncomingData(event:DataEvent):void
{
        trace("[" + event.type + "] " + event.data);
	output_txt.text += event.data + "\n";
	output_txt.verticalScrollPosition = output_txt.maxVerticalScrollPosition;
}

Minimal code at best but enough to demo the Chat program. I’m using port 80 so make sure to modify that if you already have something running on that port. Also you will need to add a policy file and serve the policy file if you intend to run this outside of the Flash CS4 IDE otherwise you’ll get a security issue.

So fire up the socket server and run the Flash program and you should be able to do some chatting.

Starting the chat socket server

Chat Application Running

Post to Twitter

This entry was posted in ActionScript, Flash, Python, Socket Server, Ubuntu. Bookmark the permalink.

One Response to Building a Flash Chat Socket Server with Stackless Python

  1. Richard Tew says:

    Note that stacklesssocket is based on select, which on Windows can only support 512 concurrent connections.

Comments are closed.