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