[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Fwd: Re: [pygame] Example: Simple client and server



On Thursday 04 October 2007 05:04, Ian Mallett wrote:
> I mean like how would one use it?  For example, with this brilliant code,
> could one send signals to another computer and vice-versa, like:
>
> computer 1                                                 computer 2
> [sends]"Hi Comp 1"                        [receives][returns:]"Hi Comp 2"
> [receives][returns:]"How are you?"   [receives][returns:]"I'm fine."
> [receives][returns:]"Good, me too."  [receives][returns:]"Excellent."
> [receives][returns:]"Except the bug" [receives][returns:]"huh?"
> [receives][returns:]"I got sick"          [receives][returns:]"I see you're
> better now though!"
> [receives][returns:]"I got over it."       [receives][returns:]"Like I
> said, so I noticed."
> [receives][returns:]"Perceptive."       [receives][returns:]"Yep.  Opps!"
> [receives][returns:]"What?"              [receives][returns:]"I've got to
> go play tetris"
> [receives][returns:]"And leave?"       [receives][returns:]"The kids are
> making me."
> [receives][returns:]"OK"                  [receives][returns:]"Bye."
> [receives][returns:]"Bye."
>
> The idea here is to make a 2 player game where data is constantly
> exchanged, and the computers act on the data from the other computer.  I'm
> hoping this can do that?

This is actually pretty simple to do in Kamaelia, in a way very similar to
the way you express it above. If you assume in the above that "computer 1"
is the server, we can write the server like this:

class MyServer(Axon.Component.component, wait_utils):
    myscript = [ "Hi Comp 1",
                 "How are you?",
                 "Good, me too.",
                 "Except the bug",
                 "I got sick",
                 "I got over it.",
                 "Perceptive.",
                 "What?",
                 "And leave?",
                 "OK",
                 "Bye.",
    ]
    def waitinbox(self):
        def wait_inbox():
            while not self.dataReady("inbox"):
                self.pause()
                yield 1
        return WaitComplete(wait_inbox())

    def main(self):
        message_from_client = None
        i = 0
        while message_from_client != "Bye":
            self.send(self.myscript[i], "outbox")
            yield self.waitinbox()
            message_from_client = self.recv("inbox")
            print "MESSAGE FROM CLIENT:", message_from_client
            i = i + 1
        self.send(Axon.Ipc.shutdownMicroprocess(), "signal")

What you should see here is that the server waits for messages in its inbox
"inbox". (Think trays on a desk which the postal system can deliver to)
The server takes the message, joyfully announces this to the world, a then
sends the next message to the outside world by putting a message in his
outbox "outbox". Again, think of trays on a desk - someone handily comes
along and delivers them to the client.

The client side looks like this:

class MyClient(Axon.Component.component, wait_utils):
    myscript = [ "Hi Comp 2",
                 "I'm fine.",
                 "Excellent.",
                 "huh?",
                 "I see you're better now though!",
                 "Like I said, so I noticed.",
                 "Yep.  Opps!",
                 "I've got to go play tetris",
                 "The kids are making me.",
                 "Bye."
    ]
    def waitinbox(self):
        def wait_inbox():
            while not self.dataReady("inbox"):
                self.pause()
                yield 1
        return WaitComplete(wait_inbox())

    def main(self):
        message_from_server = None
        i = 0
        while message_from_server != "Bye.":
            yield self.waitinbox()
            message_from_server = self.recv("inbox")
            print "MESSAGE FROM SERVER:", message_from_server

            if message_from_server != "Bye.":
               self.send(self.myscript[i], "outbox")
               i = i+1
        self.send(Axon.Ipc.producerFinished(), "signal")

Which you can pretty much see is the same. Indeed, the only difference
between them is:
   * The contents of "myscript"
   * The fact that the client waits for a message before sending one, whereas
     the server does the opposite.

To run the server, you then do this:

SimpleServer(protocol = MyServer, port = 1500).activate()

To run the client, it's a little more involved, but we do this:

Graphline(
    HANDLER = MyClient(),
    CONNECTION = TCPClient("127.0.0.1", 1500),
    linkages = {
        # Data from the handler to the network connection (ie to the server)
        ("HANDLER", "outbox") : ("CONNECTION", "inbox"),
        ("HANDLER", "signal") : ("CONNECTION", "control"),

        # Data from the network  connection back to the handler
        # (ie from the server)
        ("CONNECTION","outbox") : ("HANDLER","inbox"),
        ("CONNECTION","signal") : ("HANDLER","control"),
    }
).run()

The idea here is we have out handler, and something that can connect to the
server. We then have to tell the system "when you see data on this outbox,
deliver it to this component's inbox".  Visually it's like this:

           HANDLER
 control inbox  outbox signal
   ^      ^        |      |

   |      |        V      V

 signal outbox   inbox control
           CONNECTION

(data goes on the obvious names of "inbox" & "outbox", shutdown info on the
"signal" & "control" boxes)

If I run this, I get this:

MESSAGE FROM SERVER: Hi Comp 1
MESSAGE FROM CLIENT: Hi Comp 2
MESSAGE FROM SERVER: How are you?
MESSAGE FROM CLIENT: I'm fine.
MESSAGE FROM SERVER: Good, me too.
MESSAGE FROM CLIENT: Excellent.
MESSAGE FROM SERVER: Except the bug
MESSAGE FROM CLIENT: huh?
MESSAGE FROM SERVER: I got sick
MESSAGE FROM CLIENT: I see you're better now though!
MESSAGE FROM SERVER: I got over it.
MESSAGE FROM CLIENT: Like I said, so I noticed.
MESSAGE FROM SERVER: Perceptive.
MESSAGE FROM CLIENT: Yep.  Opps!
MESSAGE FROM SERVER: What?
MESSAGE FROM CLIENT: I've got to go play tetris
MESSAGE FROM SERVER: And leave?
MESSAGE FROM CLIENT: The kids are making me.
MESSAGE FROM SERVER: OK
MESSAGE FROM CLIENT: Bye.
MESSAGE FROM SERVER: Bye.

I've copied and pasted the full script below. (There's one change - I moved
"waitinbox" into a separate class to allow it to be reused between the server
& client components)

In order for this to work, you need the Axon & Kamaelia packages from here:

Axon:
http://sourceforge.net/project/showfiles.php?group_id=122494&package_id=139298&release_id=451254

Kamaelia:
http://sourceforge.net/project/showfiles.php?group_id=122494&package_id=133714&release_id=451253

If anyone's curious, I can show how to change this into a simple chat system
using pygame for the interface.

Best Regards,


Michael.

 -------------------------------------------------------

#!/usr/bin/python
#
# Basic chatting server & client
#

import Axon
from Axon.Ipc import WaitComplete
from Kamaelia.Chassis.Graphline import Graphline
from Kamaelia.Internet.TCPClient import TCPClient
from Kamaelia.Chassis.ConnectedServer import SimpleServer

class wait_utils(object):
    def waitinbox(self):
        def wait_inbox():
            while not self.dataReady("inbox"):
                self.pause()
                yield 1
        return WaitComplete(wait_inbox())

class MyServer(Axon.Component.component, wait_utils):
    myscript = [ "Hi Comp 1",
                 "How are you?",
                 "Good, me too.",
                 "Except the bug",
                 "I got sick",
                 "I got over it.",
                 "Perceptive.",
                 "What?",
                 "And leave?",
                 "OK",
                 "Bye.",
    ]
    def main(self):
        message_from_client = None
        i = 0
        while message_from_client != "Bye":
            self.send(self.myscript[i], "outbox")
            yield self.waitinbox()
            message_from_client = self.recv("inbox")
            print "MESSAGE FROM CLIENT:", message_from_client
            i = i + 1
        self.send(Axon.Ipc.shutdownMicroprocess(), "signal")

class MyClient(Axon.Component.component, wait_utils):
    myscript = [ "Hi Comp 2",
                 "I'm fine.",
                 "Excellent.",
                 "huh?",
                 "I see you're better now though!",
                 "Like I said, so I noticed.",
                 "Yep.  Opps!",
                 "I've got to go play tetris",
                 "The kids are making me.",
                 "Bye."
    ]
    def main(self):
        message_from_server = None
        i = 0
        while message_from_server != "Bye.":
            yield self.waitinbox()
            message_from_server = self.recv("inbox")
            print "MESSAGE FROM SERVER:", message_from_server

            if message_from_server != "Bye.":
               self.send(self.myscript[i], "outbox")
               i = i+1
        self.send(Axon.Ipc.producerFinished(), "signal")

SimpleServer(protocol = MyServer, port = 1500).activate()

Graphline(
    HANDLER = MyClient(),
    CONNECTION = TCPClient("127.0.0.1", 1500),
    linkages = {
        # Data from the handler to the network connection (ie to the server)
        ("HANDLER", "outbox") : ("CONNECTION", "inbox"),
        ("HANDLER", "signal") : ("CONNECTION", "control"),

        # Data from the network  connection back to the handler
        # (ie from the server)
        ("CONNECTION","outbox") : ("HANDLER","inbox"),
        ("CONNECTION","signal") : ("HANDLER","control"),
    }
).run()

 -------------------------------------------------------