Object Oriented Networking Code with Panda3D Foundation

I was looking through networking examples that were posted all around the forums and most of them were not using Panda3D’s built in networking methods. I decided to write my own classes that used these Panda3D methods. I also added rencode, which is used for serialization and compression, to the classes.

All the files can be found here(including test_client.py, test_server.py, and rencode):
kijaro.p3dp.com/downloads/Networking_Code.zip

Here is the test_server.py and test_client.py for you to take a look at to see “how” the classes I built, are used.

#!/usr/bin/env python
#Client

import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import * 
from direct.task import Task 
from direct.distributed.PyDatagram import PyDatagram 
from direct.distributed.PyDatagramIterator import PyDatagramIterator 
from Client import *

class World(DirectObject):
    def __init__(self):
        # Connect to our server
        self.client = Client("127.0.0.1", 9099, compress=True)
        
        # Create a task to print and send data
        taskMgr.doMethodLater(2.0, self.printTask, "printData")
        
    def printTask(self, task):
        # Print results
        print "Received: " + str(self.client.getData())
        print "Connected: " + str(self.client.getConnected())
        
        # Setup data to send to the server
        data = {}
        data["test"] = "test"
        
        # Send data to the server
        self.client.sendData(data)
        
        return Task.again
            
w = World()
run()
#!/usr/bin/env python
#Server

import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import * 
from direct.task import Task 
from direct.distributed.PyDatagram import PyDatagram 
from direct.distributed.PyDatagramIterator import PyDatagramIterator 
from Server import *

class World(DirectObject):
    def __init__(self):
        # Start our server up
        self.server = Server(9099, compress=True)
        
        # Create a task to print and send data
        taskMgr.doMethodLater(2.0, self.printTask, "printData")
        
    def printTask(self, task):
        # Print out results
        print "Received: " + str(self.server.getData())
        print "Clients: " + str(self.server.getClients())
        
        # Broadcast data to all clients
        self.server.broadcastData("Server's Data")
        
        return Task.again
            
w = World()
run()

wow…that simple huh…looks at the tutorial wow…much more simple!!!

Well blow me down… that is nice and basic.
:smiley:

Well done. :slight_smile:

I’d now like to know what the difference between the code here:
discourse.panda3d.org/viewtopic.php?p=28553#28553

and the above is in relation to making the initial connection.

So you use self.client = Client(args) whereas this other guy manually sets up readers and writers etc.

Which way is the better?
What exactly does Client() do differently than all the other packages?

EDIT: In fact upon testing I find that Client() does not exist.

EDIT #2: Ok… Finished being stupid now.
I downloaded your thing and got it working.

Looked inside Client.py and found that in fact your code really is not any different from the other examples, just packaged much better.
Nice job. :smiley:

L:lol:L

Heh. So let “my” Code (and Yellow’s) rest?

Also a ok-with-me-decision. :slight_smile:

Regards, Bigfoot29

thx, gonna try it the next days

This is probably an obvious edit to the server to many, but here’s a version of the test_server that won’t render a window:

#!/usr/bin/env python
#Server

from pandac.PandaModules import loadPrcFileData 
loadPrcFileData("", "window-type none")

import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *
from direct.task import Task 
from direct.distributed.PyDatagram import PyDatagram 
from direct.distributed.PyDatagramIterator import PyDatagramIterator 
from Server import *

class World(DirectObject):
    def __init__(self):
        assert base.win is None
        # Start our server up
        self.server = Server(9099, compress=True)
        # Create a task to print and send data
        taskMgr.doMethodLater(2.0, self.printTask, "printData")
        
    def printTask(self, task):
        # Print out results
        print "Received: " + str(self.server.getData())
        print "Clients: " + str(self.server.getClients())
        # Broadcast data to all clients
        self.server.broadcastData("Server's Data")
        return Task.again

w = World()
run()

I wanted to see who was sending what so I added this print statement to the server.py code. Why does it give different numbers that the ones given getClients in the test server ?

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                print datagram.getConnection()
                data.append(self.processData(datagram))
        return data

A small change to Server.py
This sends a packet back to the sender with the word got added. I made it to show how you can tell who send the info.

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                con = PointerToConnection()
                con = datagram.getConnection()
                datum=self.processData(datagram)
                me = {}
                me["test"] = "got" + datum["test"]
                self.sendData(me, con)
                data.append(datum)
        return data

Link on OP’s post is dead :frowning:

1 Like