Ye Olde Clue

Random musings on random stuff.

Simple Chat Server in Kamaelia

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 :)

Reply to this post

Comments

#

 Plaxo has a python script for crawling your Open Social Graph. They mention that it's not yet multi-threaded.

-- Sam Hasler

-- guest, 13 Nov 2008 at 15:54, Rating: 0 (Reply) (Moderated by: anon)

#

 Very cool!  I love how simple it looks when parts are put together like this :)

Go pipes!

-- guest, 21 Nov 2008 at 06:52, Rating: 0 (Reply) (Moderated by: anon)

#

Thank you for your kind words. It's very much appreciated :-)

-- Michael, 21 Nov 2008 at 12:35, Rating: 0 (Reply) (Moderated by: anon)

Modifying the simple chat server to prompt for a name, and detect client disconnect #

Hi Michael,

I am trying to modify thie chat server to promot for a name, then hand control to the Pipeline. I also want it to detect disconnect, since it is a TCP connection.

I am guessing that I first need to set the protocol in the ChatServer to somethign else which will allow reads/writes from and to this client. I then need to take the second request from the client, validate them (make sure they entered a name), and then pass it to Pipeline.

Please don't write this for me. I am using this as one of the examples I'll show at PyCon (My goal is to have several simple examples, and walk through them line by line. I've been quietly putting them together, and this looks like a nifty new one :). Just point me in the correct general direction. Which protocol would I use to get access to this client's inbox and outbox? Can I do anything else inside of ChatServer other than pass it parameters?

Also, why does it take so long for the server port to be released between invocations?

Sadly, this demo may be cancelled, due to not meeting the minimum requirement of ten attendees. But I'll keep preparing these until I hear otherwise. I am enjoying this immensely, regardless of presenting or not.

Thanks again, keep them coming!

Gloria

strangest at comcast dot net

-- guest, 1 Mar 2009 at 03:03, Rating: 0 (Reply) (Moderated by: anon)

Back to front page