写了个很简单的chat,以后会慢慢加进功能, 主要用到wxpython+twisted, 里面主要碰到一个问题,wxpython的mainloop和twisted的reactor.run()如果并存,会有问题。可以通过reactor.registerWxApp(app)解决..
ChatClient.py
<textarea cols="50" rows="15" name="code" class="python:collapse:showcolumns"># -*- coding: UTF-8 -*- import wx; import wx.richtext as rt; import SPrint; from twisted.internet import wxreactor wxreactor.install() from twisted.internet import reactor,protocol class EchoClient(protocol.Protocol): """chat client"""; F = ""; def connectionMade(self): print "connection success"; def dataReceived(self,data): print "-----dataReceived: " + data; self.F(data); def connectionLost(self,reason): "" def send(self,s): print "send: " + s self.transport.write( str(s + '/r/n') ); class EchoFactory(protocol.ClientFactory): echoCL = ''; clientSendFun = ''; def startConnect(self,fun): print "-----startConnect" self.clientSendFun = fun; def buildProtocol(self, addr): print "-----buildProtocol" self.echoCL = EchoClient(); self.echoCL.factory = self; self.echoCL.F = self.clientSendFun; return self.echoCL; def sendText(self,s): self.echoCL.send(s); #def startedConnecting(self,connector): #print "Connection success!"; def clientConnectionFailed(self,connector,reason): print "Connection failed handle"; reactor.stop(); def clientConnectionLost(self, connector, reason): print "Connection lost handle" reactor.stop() class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self,None,-1,"chat",size=(500,400),style=wx.DEFAULT_FRAME_STYLE); self.allText = ''; self.loginName = ''; self.richText = rt.RichTextCtrl(self,-1,style=wx.VSCROLL|wx.HSCROLL); self.richText.SetEditable(False); self.loginText = wx.TextCtrl(self,-1,size=(300,25)) self.loginBtn = wx.Button(self,wx.NewId(),"login",size=(50,30)); self.loginBtn.Bind(wx.EVT_BUTTON,self.login,self.loginBtn); self.sendText = wx.TextCtrl(self,-1,size=(300,25)) self.sendBtn = wx.Button(self,wx.NewId(),"send",size=(50,30)); self.sendBtn.Bind(wx.EVT_BUTTON,self.sendTextHandle,self.sendBtn); topSizer = wx.BoxSizer(wx.HORIZONTAL); topSizer.Add((5,5),0) topSizer.Add(self.loginText,1,wx.EXPAND|wx.ALL,5); topSizer.Add((5,5),0); topSizer.Add(self.loginBtn); topSizer.Add((5,5),0); bottomSizer = wx.BoxSizer(wx.HORIZONTAL); bottomSizer.Add((5,5),0) bottomSizer.Add(self.sendText,1,wx.EXPAND|wx.ALL,5); bottomSizer.Add((5,5),0); bottomSizer.Add(self.sendBtn); bottomSizer.Add((5,5),0); mainsizer = wx.BoxSizer(wx.VERTICAL); mainsizer.Add(topSizer,0,wx.EXPAND|wx.ALL,5); mainsizer.Add(self.richText,1,wx.EXPAND|wx.ALL,5); mainsizer.Add((5,5),0); mainsizer.Add(bottomSizer,0,wx.EXPAND|wx.ALL,5); self.SetSizer(mainsizer); self.SetFocus(); self.setEnabled(True); def setEnabled(self,b): self.richText.Enable(b) self.sendText.Enable(b) self.sendBtn.Enable(b) def login(self,event): self.loginSuc(self.loginText.GetValue()); def loginSuc(self,name=''): if(name!=''): self.loginName = self.loginText.GetValue(); self.fact = EchoFactory() self.fact.startConnect(self.getTEXT); reactor.connectTCP( "localhost",1234 , self.fact ); def sendTextHandle(self,event): self.fact.sendText("<font color='#cc0000'>" + self.loginName +'</font> say: ' + self.sendText.GetValue()); def getTEXT(self,s=''): #self.allText += s; self.richText.AppendText(s); def reflashTEXT(self): self.richText.SetValue(self.allText); class MyApp(wx.App): def OnInit(self): frame = MyFrame() frame.Show(True) self.SetTopWindow(frame) return True; def demo(): app = MyApp(0) reactor.registerWxApp(app) #reactor.connectTCP( "localhost",1234 , EchoFactory() ); reactor.run(0) if __name__ == '__main__': demo() </textarea>
ChatServer.py
<textarea cols="50" rows="15" name="code" class="python:collapse:showcolumns"># -*- coding: UTF-8 -*- from twisted.internet import reactor; from twisted.internet import protocol; from twisted.protocols import basic; from twisted.internet.protocol import Protocol,Factory; from twisted.protocols.basic import LineReceiver; from twisted.application import service,internet; class ChatServer(basic.LineReceiver): print "server running......" def connectionMade(self): print "Get connection from: " , self.transport.client; #self.message("Connection success!/n") self.factory.clients.append(self); #reason: twisted.python.failure.Failure; def connectionLost(self,reason): print "connection lost: " , reason.getErrorMessage(); self.factory.clients.remove(self); def lineReceived(self,line): print "rec data: " , line; for cl in self.factory.clients: cl.message(line); def message(self,message): self.transport.write(message+'/r/n'); factory = protocol.ServerFactory() factory.protocol = ChatServer factory.clients = [] ; #application = service.Application("chatserver") #internet.TCPServer(1234, factory).setServiceParent(application) reactor.listenTCP(1234,factory) reactor.run() </textarea>