Simple Chat Server in Kamaelia

November 13, 2008 at 11:00 AM | categories: python, oldblog | View Comments

On the #kamaelia IRC channel , the issue was raised that a number of the examples on the Kamaelia website are just that, small examples, perhaps too small to be useful beyond illustrating the basic idea. (I'm not sure this is universally true, but I accept its definitely the place in more places than we'd like!). Now, one thing we've got planned for the december release is to include a lot more examples, and as a result I'm interested in hearing what sort of examples people would find useful. For example, the example mentioned on the channel is "what does a simple chat server look like" ? (and hence why I'm interested in what examples people would find interesting/useful)

Well, the reason there wasn't an example of that up is because it's a really trivial example in Kamaelia. The most basic version for example looks like this:
from Kamaelia.Util.Backplane import Backplane, PublishTo, SubscribeTo
from Kamaelia.Chassis.ConnectedServer import ServerCore
from Kamaelia.Chassis.Pipeline import Pipeline

Backplane("CHAT").activate()  # This handles the sharing of data between clients

def ChatClient(*argv, **argd):
     return Pipeline(
                 PublishTo("CHAT"), # Take data from client and publish to all clients
                 SubscribeTo("CHAT"), # Take data from other clients and send to our client
            )

print "Chat server running on port 1501"
ServerCore(protocol = ChatClient, port=1501).run()
A slightly more interesting version, which at least tells clients who they're talking to, and also has slightly better (more explicit) structure is this:
#!/usr/bin/python

from Kamaelia.Util.Backplane import Backplane, PublishTo, SubscribeTo
from Kamaelia.Chassis.ConnectedServer import ServerCore
from Kamaelia.Chassis.Pipeline import Pipeline
from Kamaelia.Util.PureTransformer import PureTransformer

Backplane("CHAT").activate()  # This handles the sharing of data between clients

def ChatClient(*argc, **argd):
     peer = argd["peer"]
     peerport = argd["peerport"]
     return
Pipeline(
                 PureTransformer(lambda x: " %s:%s says %s" % (str(peer), str(peerport), str(x))),
                
PublishTo("CHAT"), # Take data from client and publish to all clients
                 # ----------------------
                
SubscribeTo("CHAT"), # Take data from other clients and send to our client
                 PureTransformer(lambda x: "Chat:"+ str(x).strip()+"\n"),
            )

class ChatServer(
ServerCore):
    protocol = ChatClient

print "Chat server running on port 1501"

ChatServer(port=1501).run()
To try this yourself:
Then telnet to 127.0.0.1, port 1501

A nice Pygame based client for this looks like this incidentally:
from Kamaelia.Chassis.Pipeline import Pipeline
from Kamaelia.UI.Pygame.Text import Textbox, TextDisplayer
from Kamaelia.Internet.TCPClient import
TCPClient

Pipeline(
        
Textbox(size = (800, 300), position = (100,380)),
        
TCPClient("127.0.0.1", 1501),
        
TextDisplayer(size = (800, 300), position = (100,40))
).run()
To run that (assuming you have pygame installed):
Which looks like this:


Now there's clearly a lot interesting directions you can take this, but as you can see, this is a relatively simple starting point. For something more complex, there is a basic P2P splitting radio system in our subversion tree. It's just over a 100 lines long for the source side (ie capturing radio off air and serving it), and the client is a similar size (has a playback component rather than capture one). The code for those two examples is here:
The two examples actually contain a lot of common code, so we could extract the common code and have two smaller examples, but like this the files are standalone, which is pretty nice.

Anyway, the point of this post was "what sort of examples would you like to see?" and I'm really interested in any feedback :-)

Have fun :)
blog comments powered by Disqus