I want to create a chat in panda3D. How do I do this?
Thank you.
I want to create a chat in panda3D. How do I do this?
Thank you.
Well, you should be a little more specific before you expect someone to answer your problem like you intended.
But to answer your question as best I can, I’d reccommend using a library besides Panda to implement a chatting backend. Perhaps Twisted or asynchat would help.
why would someone suggesting to use 3rd party libs when panda comes with a complete networking stack?
anyway, the manual provides valuable information on how to send data over the network.
panda3d.org/manual/index.php/Networking
for a complete chat you also need the DirectScrolledList and a DirectEntry for typing.
I suggested asynchat as it’s in the Python Standard Library, as well as being substantially simpler than Panda’s networking API. I suggested Twisted as it’s also a popular choice, and probably offers better performance than anything Panda has to offer.
Nothing against Panda’s networking stack, just an opinion…
Thanks for your responses.
I found the next code, but there’s an error.
I have windows 7 home premium 64 bits
Client Side. The error is in this part.
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import ConfigVariableString
ConfigVariableString("window-type", "none").setValue("none")
import direct.directbase.DirectStart
from direct.task import Task
from pandac.PandaModules import QueuedConnectionManager, QueuedConnectionReader, ConnectionWriter, QueuedConnectionListener
from direct.distributed.PyDatagram import PyDatagram
from direct.distributed.PyDatagramIterator import PyDatagramIterator
class Client(DirectObject):
def __init__( self ):
print "Initializing client test"
self.port = 9099
self.ip_address = "localhost"
self.timeout = 3000 # 3 seconds to timeout
self.cManager = QueuedConnectionManager()
self.cListener = QueuedConnectionListener(self.cManager, 0)
self.cReader = QueuedConnectionReader(self.cManager, 0)
self.cWriter = ConnectionWriter(self.cManager,0)
self.Connection = self.cManager.openTCPClientConnection(self.ip_address, self.port, self.timeout)
if self.Connection:
taskMgr.add(self.tskReaderPolling,"read the connection listener",-40)
# this tells the client to listen for datagrams sent by the server
print "Connected to Server"
self.cReader.addConnection(self.Connection)
PRINT_MESSAGE = 1
myPyDatagram = PyDatagram()
myPyDatagram.addUint8(100)
# adds an unsigned integer to your datagram
myPyDatagram.addString("first string of text")
# adds a string to your datagram
myPyDatagram.addString("second string of text")
# adds a second string to your datagram
self.cWriter.send(myPyDatagram, self.Connection)
# fires it off to the server
#self.cManager.closeConnection(self.Connection)
#print "Disconnected from Server"
# uncomment the above 2 lines if you want the client to
# automatically disconnect. Or you can just
# hit CTRL-C twice when it's running to kill it
# in windows, I don't know how to kill it in linux
else:
print "Not connected to Server"
def tskReaderPolling(self, task):
if self.cReader.dataAvailable():
datagram=PyDatagram()
if self.cReader.getData(datagram):
self.processServerMessage(datagram)
return Task.cont
def processServerMessage(self, netDatagram):
myIterator = PyDatagramIterator(netDatagram)
print myIterator.getString()
Client = Client()
run()
SERVER SIDE
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
from pandac.PandaModules import ConfigVariableString
ConfigVariableString("window-type", "none").setValue("none")
import direct.directbase.DirectStart
# These are the Panda libraries needed for everything else
# to function properly. The configvariable bit disables the
# standard window that opens, as the server doesn't need to continually
# re-draw a window - it just needs to to output to the command prompt
from panda3d.core import *
from pandac.PandaModules import QueuedConnectionManager, QueuedConnectionReader, ConnectionWriter, QueuedConnectionListener, NetAddress
from direct.distributed.PyDatagram import PyDatagram
from direct.distributed.PyDatagramIterator import PyDatagramIterator
# panda's built-in networking code for TCP networking
class Server(DirectObject):
def __init__( self ):
self.port = 9099
self.portStatus = "Closed"
self.host = "localhost"
self.backlog = 1000
self.Connections = {}
# basic configuration variables that are used by most of the
# other functions in this class
self.StartConnectionManager()
# manages the connection manager
self.DisplayServerStatus()
# output a status box to the console which tells you the port
# and any connections currently connected to your server
def DisplayServerStatusTASK(self, task):
# all this does is periodically load the status function below
# add a task to display it every 30 seconds while you are doing
# any new coding
self.DisplayServerStatus()
return Task.again
def DisplayServerStatus(self):
print "\n----------------------------------------------------------------------------\n"
print "SERVER STATUS:\n\n"
print "Connection Manager Port: " + str(self.port) + " [" + str(self.portStatus) + "]"
for k, v in self.Connections.iteritems():
print "Connection " + k
##################################################################
# TCP Networking Functions and Tasks
##################################################################
def StartConnectionManager(self):
# this function creates a connection manager, and then
# creates a bunch of tasks to handle connections
# that connect to the server
self.cManager = QueuedConnectionManager()
self.cListener = QueuedConnectionListener(self.cManager, 0)
self.cReader = QueuedConnectionReader(self.cManager, 0)
self.cWriter = ConnectionWriter(self.cManager,0)
self.tcpSocket = self.cManager.openTCPServerRendezvous(self.port,self.backlog)
self.cListener.addConnection(self.tcpSocket)
self.portStatus = "Open"
taskMgr.add(self.ConnectionManagerTASK_Listen_For_Connections,"Listening for Connections",-39)
# This task listens for new connections
taskMgr.add(self.ConnectionManagerTASK_Listen_For_Datagrams,"Listening for Datagrams",-40)
# This task listens for new datagrams
taskMgr.add(self.ConnectionManagerTASK_Check_For_Dropped_Connections,"Listening for Disconnections",-41)
# This task listens for disconnections
def ConnectionManagerTASK_Listen_For_Connections(self, task):
if(self.portStatus == "Open"):
# This exists in case you want to add a feature to disable your
# login server for some reason. You can just put code in somewhere
# to set portStatus = 'closed' and your server will not
# accept any new connections
if self.cListener.newConnectionAvailable():
print "CONNECTION"
rendezvous = PointerToConnection()
netAddress = NetAddress()
newConnection = PointerToConnection()
if self.cListener.getNewConnection(rendezvous,netAddress,newConnection):
newConnection = newConnection.p()
self.Connections[str(newConnection.this)] = rendezvous
# all connections are stored in the self.Connections
# dictionary, which you can use as a way to assign
# unique identifiers to each connection, making
# it easy to send messages out
self.cReader.addConnection(newConnection)
print "\nSOMEBODY CONNECTED"
print "IP Address: " + str(newConnection.getAddress())
print "Connection ID: " + str(newConnection.this)
print "\n"
# you can delete this, I've left it in for debugging
# purposes
self.DisplayServerStatus()
# this fucntion just outputs the port and
# current connections, useful for debugging purposes
return Task.cont
def ConnectionManagerTASK_Listen_For_Datagrams(self, task):
if self.cReader.dataAvailable():
datagram=NetDatagram()
if self.cReader.getData(datagram):
print "\nDatagram received, sending response"
myResponse = PyDatagram()
myResponse.addString("GOT YER MESSAGE")
self.cWriter.send(myResponse, datagram.getConnection())
# this was just testing some code, but the server will
# automatically return a 'GOT YER MESSAGE' datagram
# to any connection that sends a datagram to it
# this is where you add a processing function here
#myProcessDataFunction(datagram)
return Task.cont
def ConnectionManagerTASK_Check_For_Dropped_Connections(self, task):
# if a connection has disappeared, this just does some house
# keeping to officially close the connection on the server,
# if you don't have this task the server will lose track
# of how many people are actually connected to you
if(self.cManager.resetConnectionAvailable()):
connectionPointer = PointerToConnection()
self.cManager.getResetConnection(connectionPointer)
lostConnection = connectionPointer.p()
# the above pulls information on the connection that was lost
print "\nSOMEBODY DISCONNECTED"
print "IP Address: " + str(lostConnection.getAddress())
print "ConnectionID: " + str(lostConnection.this)
print "\n"
del self.Connections[str(lostConnection.this)]
# remove the connection from the dictionary
self.cManager.closeConnection(lostConnection)
# kills the connection on the server
self.DisplayServerStatus()
return Task.cont
Server = Server()
run()
The error is the next
DirectStart: Starting the game.
Initializing client test
Connected to Server
Assertion failed: _current_index < _datagram->get_length() at line 199 of c:\bui
ldslave\dev_sdk_win32\build\panda3d\panda\src\express\datagramIterator.I
Traceback (most recent call last):
File "c:/proyectos/ej2.py", line 65, in tskReaderPolling
self.processServerMessage(datagram)
File "c:/proyectos/ej2.py", line 72, in processServerMessage
print myIterator.getString()
AssertionError: _current_index < _datagram->get_length() at line 199 of c:\build
slave\dev_sdk_win32\build\panda3d\panda\src\express\datagramIterator.I
:task(error): Exception occurred in PythonTask read the connection listener
Traceback (most recent call last):
File "c:/proyectos/ej2.py", line 78, in <module>
run()
File "C:\Program Files (x86)\Panda3D-1.8.0\direct\showbase\ShowBase.py", line
2630, in run
self.taskMgr.run()
File "C:\Program Files (x86)\Panda3D-1.8.0\direct\task\Task.py", line 502, in
run
self.step()
File "C:\Program Files (x86)\Panda3D-1.8.0\direct\task\Task.py", line 460, in
step
self.mgr.poll()
File "c:/proyectos/ej2.py", line 65, in tskReaderPolling
self.processServerMessage(datagram)
File "c:/proyectos/ej2.py", line 72, in processServerMessage
print myIterator.getString()
AssertionError: _current_index < _datagram->get_length() at line 199 of c:\build
slave\dev_sdk_win32\build\panda3d\panda\src\express\datagramIterator.I
tho code works well for me. ubuntu 10.04_64. any chance windwos ‘advanced security’ features are interfering?
I checked the firewall, this code if it works in windows xp, but not it works in windows 7. Do you have some idea?
thanks