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.
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()
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