python - Twisted TCP server with a Tkinter GUI -


recently i've been experimenting twisted (python library) in attempt make tcp chat server/client. had server running nicely when tried add tkinter-based gui server, things got weird. user connects server, message sent gui. however, somewhere along way goes wrong , long-winded error comes up, gist of tkinter ran out of stack space because of infinite loop. i've put code below. function having trouble app.write(text) , user.connectionmade(*args) other function in user class attempts print text gui.

from twisted.internet.protocol import serverfactory, protocol twisted.internet import reactor os import path import yaml import threading tkinter import *  __version__ = '' __author__ = ''  class user(protocol):     def connectionmade(self,*args):         self.gui.write('new connection %s' % (self.addr.host))         self.transport.write('username: ')      def connectionlost(self,reason):         self.gui.write('connection lost %s' % (self.addr.host))         if not self.name == none:             msg = '%s has disconnected\r\n' % (self.name)             self.gui.write(msg.rstrip())             self.toall(msg)             del self.users[self.name]      def datareceived(self,data):         if data == '\x08':             if len(self.text) > 0:                 self.text = self.text[:-1]             return          elif not data.endswith('\r\n'):             self.text += data             return         if self.name == none:             self.setname(self.text)         else:             self.handle(self.text)         self.text = ''      def handle(self,data):         if not data.startswith('/'):             self.chat(data)         else:             self.gui.write('%s executed command %s' % (self.name, data))             if data in ['/help','/h']: self.cmdhelp()             elif data in ['/list','/l']: self.userlist()             elif data in ['/motd','/m']: self.sendmotd()             elif data in ['/ping','/p']: self.transport.write('pong!\r\n')             else: self.transport.write('unrecognized command %s\r\n' % (data))      def cmdhelp(self):         x = ['\r\ncommands:',\              '/motd,/m - display motd',\              '/list,/l - display list of online users',\              '/help,/h - display list\r\n']         item in x:             self.transport.write(item+'\r\n')      def sendmotd(self):         self.transport.write('\r\nmotd: %s\r\n\r\n' % (self.motd))      def userlist(self):         self.transport.write('\r\ncurrently online: server,%s\r\n\r\n' % (','.join(item item in self.users)))      def setname(self,name):         if self.users.has_key(name) or name.lower() == 'server':             self.transport.write('that username in use!\r\nusername: ')         elif ' ' in name:             self.transport.write('no spaces allowed in usernames!\r\nusername: ')         elif name == '':             self.transport.write('you must enter username!\r\nusername: ')         else:             self.users[name] = self             self.name = name             self.gui.write('new user registered %s' % (name))             self.toall('%s has connected' % (self.name))             self.transport.write('\nsuccessfully logged in %s\r\n\r\n' % (name))             self.sendmotd()      def toall(self,msg):         name,protocol in self.users.iteritems():             if not protocol == self:                 protocol.transport.write(msg)      def chat(self,data):         to_self = '<%s (you)> %s\r\n' % (self.name, data)         to_else = '<%s> %s\r\n' % (self.name, data)         self.gui.write('[chat] - %s' % (to_else.rstrip()))         self.transport.write(to_self)         self.toall(to_else)      def __init__(self,addr=none,users=none,motd=none,master=none):         self.name = none         self.addr = addr         self.users = users         self.motd = motd         self.text = ''         self.factory = master         self.gui = self.factory.app         self.kicked = false  class app(frame):     def write(self,text):         self.display.insert(end,text+'\n')      def clear(self,event=none):         self.display.delete(1.0,end)      def userlist(self):         self.write('currently online: server,%s' % (','.join(item item in self.factory.users)))      def handle(self,event=none):         msg = self.entry.get()         self.entry.delete(0,end)         if not msg.startswith('/'): self.send(msg)         elif msg in ['/cls','/clear','/clr','/c']: self.clear()         elif msg in ['/list','/l']: self.userlist()         elif msg in ['/exit']: self.kill()         else: self.write('unrecognized command \'%s\'' % (msg))      def send(self,msg,event=none):         item in self.factory.users: self.factory.users[item].transport.write('<server> %s\r\n' % (msg))         self.write('[chat] - <server> %s' % (msg))      def kill(self):         self.write('stopping server...')         reactor.stop()         self.write('gui says guidbye! :(')         self.quit()      def __init__(self,master,factory):         frame.__init__(self,master)         self.grid(row=0,sticky=n+e+s+w)         self.columnconfigure(0,weight=1)         self.rowconfigure(0,weight=1)          self.display = text(self)         self.display.grid(row=0,sticky=n+e+s+w)         self.yscroll = scrollbar(self,command=self.display.yview)         self.yscroll.grid(row=0,column=1,sticky=n+s)         self.display.config(yscrollcommand=self.yscroll.set)         self.entry = entry(self)         self.entry.grid(row=1,sticky=e+w)         self.master = master          self.master.wm_title('tcp chat server v%s' % (__version__))         self.factory = factory          self.motd = ''         self.port = 0          self.entry.bind('<return>',self.handle)         self.master.protocol('wm_delete_window',self.kill)          self.write('tcp chat server v%s' % (__version__))         self.write('by %s\n' % (__author__))         self.write('server running on port %s' % (self.factory.port))  class main(serverfactory):     def buildprotocol(self,addr):         return user(addr=addr,users=self.users,motd=self.motd,master=self)      def start(self):         self.root = tk()         self.root.columnconfigure(0,weight=1)         self.root.rowconfigure(0,weight=1)          self.app = app(self.root,self)         self.app.mainloop()      def __init__(self,motd,port):         self.users = {}         self.motd = motd         self.port = port          self.tk_thread = threading.thread(target=self.start)         self.tk_thread.start()   if not path.isfile('config.yml'):     open('config.yml','w').write('port: 4444\nmotd: no motd set!')  open('config.yml','r') f:     dump = yaml.load(f.read())     motd = dump['motd']     port = dump['port']  reactor.listentcp(port,main(motd,port)) reactor.run() 

everything else running expected, , when comment out app.write('') statements, program runs expected (sans gui , server-side messages). i've been using windows test program use

telnet localhost 4444 

to run client.

twisted has specialised support tkinter.

from tkinter import * twisted.internet import tksupport, reactor  root = tk()  # install reactor support tksupport.install(root)  # @ point build tk app usual using root object, # , start program "reactor.run()", , stop # "reactor.stop()". 

Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -