Network / chat problem

Hi there

im trying to make a chatroom using the panda3d

Using the code examples ive got a network connection running.
i also used the gui tutorial to get a UI running.
but when i combine the 2 i get problems.

My directentry keeps refreshing and mytextObjec gets blurry after some time.

my code for the server http://rafb.net/p/9GY5Yk54.html
my code for the client http://rafb.net/p/vEDyBL87.html

i think that the problem in the client is the World() class being called all the time, but i dont seem to be able to stop that.

is it bte nesesary to keep running world() class to receive data or should 1 instance f the class be enough?

it seems im either not formulating my question good enough or noone knows the answer. so ill try explaiing the problem.

we are making a small game that will use a lobby to make players meet up before gaming.

in the lobby there will be a server run chat

So what we need is a client server chat.
does anyone have code lying around for something like that or do you have any idea how to do it ?

Well, the links to your code don’t work, so we can’t see whats wrong with it…

oh sry. seems to decay fast.

il post here

Server code

#!/usr/bin/env python

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(54000, compress=True)
        self.myVar = "test"
        # Create a task to print and send data
        taskMgr.doMethodLater(2.0, self.printTask, "printData")
        
		
		
    def printTask(self, task):
        # Print out results
        self.myVar = str(self.server.getData())
        #print "Received: " + str(self.server.getData())
        if self.myVar != "[]":
			print "Received: " + self.myVar
			print "Clients: " + str(self.server.getClients())
			self.server.broadcastData( self.myVar )
        
		
        
        
        return Task.again
            
w = World()
run()

Client code

#!/usr/bin/env python


import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject 
from direct.task import Task 
from direct.distributed.PyDatagram import PyDatagram 
from direct.distributed.PyDatagramIterator import PyDatagramIterator 
from Client import *
 
#uiMode defines current screen (login, game mode selection, etc)
uiMode = "connect"
#see Ui class
uiCount = 0
 
class Ui():
 def __init__(self):	
	#bgImg = loader.loadTexture("mystuff/background1.png")
	#bg = OnscreenImage(image=bgImg,scale=(2,1,1))
	#add some text
	bk_text = "This is my Demo"
	self.textObject = OnscreenText(text = bk_text, pos = (0.95,-0.95), 
	scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1)
	#methods
	self.ipField = DirectEntry(text = "" ,scale=.05,command=self.setText,pos = (-.2,0,0),
	initialText="Enter host ip", numLines = 1,focus=1)
 
	self.confirm = DirectButton(text = "confirm ip", pos = (0,0,-0.1), scale = 0.05, command = self.confirmIp)
 
 def setText(self, textEntered):
		textVar1 = textEntered
		print textVar1
		self.textObject.setText(textVar1)
		w = World()
 
 def clearText(self):
		self.ipField.enterText('')
 
 
 def confirmIp(self):
		textVar1 = self.ipField.get()
		print textVar1
		self.textObject.setText(textVar1)
		w = World()
		#self.textObject.setText("check")
 
 def getIp(self):
		return self.ipField.get()
 
 
 #Variable confirming ui-existence (1 means there is a ui, 0 means there isn't)
 uiCount = 1
 
 
if uiCount==0:
	ui = Ui()
 
class World():
 
 def __init__(self):
		self.data = "Hello"
		self.connection = ui.getIp()
        # Connect to our server
		# Servername >can< now be replaced by self.connection, as long as it is a valid ip (will make addition for port tomorrow).
		self.client = Client("80.163.43.233", 54000, compress=True)
 
 
        # Create a task to print and send data
		taskMgr.doMethodLater(2.0, self.printTask, "printData")
 
 
 
 def sendWord (self):
	#sends "Hello" to server on command
	self.client.sendData(self.data)
	print str(self.client.getData())
 def printTask(self, task):
 
	# Print results
 	print "Connected: " + str(self.client.getConnected()) 
 
 
	print self.connection
	print str(self.client.getData())
 
 
	#button to send "Hello" to server on command
	self.sendHello = DirectButton(text="Send Hello!",pos=(-0.5,0,0),command=self.sendWord, scale=0.07)
 
 
 
 
        #return Task.again
 
 
 
#run the tutorial
run()

I don’t get it, you’re never instantiating the World class in your client code - shouldn’t you be adding a “w=World()” line before the run() call?

well i tried that in my first attemt, but my text field kept being deleted

this is the other client code we made


#!/usr/bin/env python
 
 
import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject 
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", 54000, compress=True)
        data =""
 
        # Create a task to print and send data
        taskMgr.doMethodLater(2.0, self.printTask, "printData")
       
 
 
 
 
    def printTask(self, task):
 
        data = ""
 
		    #callback function to set  text 
        def setText(textEntered):
	        self.client.sendData(textEntered)
 
 
            #clear the text
        def clearText():
	        b.enterText('')	
 
 
 
 
 
 
	  #add some text
 
 
 
        bk_text = "received" +str(self.client.getData())
        textObject = OnscreenText(text = bk_text, pos = (0.9,-0.9), 
        scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1)	
 
        # Print results
 
        #print "Connected: " + str(self.client.getConnected())
 
        #add button
        b = DirectEntry(text = "" ,scale=.05,command=setText,
        initialText="Type Something", numLines = 2,focus=1,focusInCommand=clearText)  
 
 
 
 
 
 
        return Task.again
 
 
w = World()

 
 
 
#run the tutorial
run()

Instantiating the world class in the DirectEntry command function doesn’t seem like a good idea, imho.
Your code is quite messy so I’m afraid I can’t really make much out of it.

i dont know if this will make it easier to see

http://rafb.net/p/iK9CQh70.html

link only last 24 hours.

Hmmm, yea I cant understand your code either, its a little to messy, but i’ll still try and help out with some simple ideas that I had with my own chat program. (also note I did it as simple as I could with my learning understanding)

Also note I didnt test this code, and I did it on the fly x.x;

  1. Make a echo server using a TCP connection that will bind to your ip (aka change your ip to your ip or if your behind a router, the ip your router gived you)
import socket
import select
import string

def broadcast_data (sock, message): 
    for socket in CONNECTION_LIST:
        if socket != server_socket and socket != sock:            
            socket.send(message)
            print message
if __name__ == "__main__":
    CONNECTION_LIST=[]
    RECV_BUFFER=1014
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("Your ip", 4999))
    server_socket.listen(10)
    CONNECTION_LIST.append(server_socket)
    print "TCP/IP Chat server process started."
    while True:
        read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
        for sock in read_sockets:
            if sock == server_socket:
                sockfd, addr = server_socket.accept()
                CONNECTION_LIST.append(sockfd)
                print "Client (%s, %s) connected" % addr
                broadcast_data(sockfd, "Client (%s, %s) connected" % addr)
            else:
                try:
                    data = sock.recv(RECV_BUFFER)
                    print data
                except:
                    broadcast_data(sock, "Client (%s, %s) isoffline" % addr)
                    print "Client (%s, %s) isoffline" % addr
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                    continue
                if data:
                  temp = data
                  data2 = temp.split()
                  if data2[0] == "q" or data2[0] == "Q":
                    broadcast_data(sock, "Client (%s, %s) quits" % addr)
                    print "Client (%s, %s) quits" % addr
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                  else:
                    broadcast_data(sock, data)                      
                
server.close()
  1. Then set up a the client, sadly I setup mine with another thread, witch people are going to tell you thats not what you should do, but I cant figure it out myself around it.
import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.OnscreenImage import OnscreenImage 
from direct.gui.DirectGui import *
import sys,socket,random,time,select,threading,os,math
from pandac.PandaModules import *
from pandac.PandaModules import NodePath
from direct.showbase.DirectObject import DirectObject

class World(DirectObject): 
    def __init__(self): 
      self.client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
      self.client.connect (("192.168.1.100", 4999)) 
      self.runthread = 1 
      self.Chat()
      
      
      
      self.x = -1
      self.a = 0
      self.Name = "Me" + str(self.a + 1)

    def send_data(self,textEntered): 
      if self.Textenter.get() == "": 
        print "cant send" 
        self.Textenter['focus'] = 1 
      else: 
        self.runthread = 0
        self.text = TextNode('w')
        self.data = self.Name+"> "+self.Textenter.get() 
        self.text.setText(self.Name+"> "+self.Textenter.get())
        self.textNodePath = aspect2d.attachNewNode(self.text) 
        self.textNodePath.setScale(0.06) 
        self.Textenter.enterText('') 
        self.myScrolledList.addItem(self.textNodePath) 
        self.client.send(self.data)
        self.client.send(self.data) 
        self.Textenter['focus'] = 1 
        self.x = self.x + 1 
        self.myScrolledList.scrollTo(self.x) 
        self.runthread = 1 

    def recv_data(self): 
      while self.runthread: 
        if self.client.recv(1024) == "": 
          break 
        else: 
         TextNode
         self.readtext = TextNode('r')
         self.data = self.client.recv(1024) 
         self.readtext.setText(self.data)
         self.readtextNodePath = aspect2d.attachNewNode(self.readtext) 
         self.readtextNodePath.setScale(0.06) 
         self.data = self.readtextNodePath 
         self.myScrolledList.addItem(self.readtextNodePath) 
         self.x = self.x + 1 
         self.myScrolledList.scrollTo(self.x) 

    def Chat(self):
      self.read = threading.Thread(target=self.recv_data)    
      self.read.isDaemon() 
      self.read.start() 
      self.Textenter = DirectEntry(pos=(-1.05,0,-.92),scale=.08,width=25,text_scale=(.8,.8),rolloverSound=0,clickSound=0,cursorKeys=1,command=self.send_data,focus=1)  
      self.myScrolledList = DirectScrolledList( 
        decButton_pos= (.85, 0, 0.2),decButton_text = "/\\",decButton_text_scale = 0.08,decButton_borderWidth = (0.005, 0.005), 
        incButton_pos= (.85, 0, 0.1),incButton_text = "\/",incButton_text_scale = 0.08,incButton_borderWidth = (0.005, 0.005), 
        numItemsVisible = 15,forceHeight = .11,itemFrame_frameSize = (-0.06, 1.8, -1.6, 0.08),itemFrame_pos = (-1, 0, .8) 
        ) 
World() 
run() 

in the client i get the error

File “client.py”, line 7, in
class World(DirectObject):
NameError: name ‘DirectObject’ is not defined

Sorry my bad, like I said I didn’t test the code. Here add this stuff to the client code. Update* I updated the code above to have this stuff so it should work from there too for a faster copy paste.

Add this to the beginning with the rest of the top stuff

import direct.directbase.DirectStart 
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.OnscreenImage import OnscreenImage 
from direct.gui.DirectGui import * 
import sys,socket,random,time,select,threading,os,math 
from direct.showbase.DirectObject import DirectObject #forgot to add this

This at the end of all the code

World()
run()

ok i added the stuff and now both client and server execute smoothly.

however, nothing seems to happen and the gui is blank ?

i set the ip of both sever and client to “localhost” that should be fine right?

Yup, let me see whats wrong with the code really fast and i’ll get back to you on that.

Look up to the 1st code again, got it 100% working.

localhost or 127.0.0.1

For? Setting up the ip and stuff? It be your localhost.

yes,

tools.ietf.org/html/rfc3330