Seite 1 von 1
Chatclient mit twisted
Verfasst: Montag 23. Oktober 2006, 21:42
von da_hui
Hi,
ich beschäftige mich jetzt schon seit einigen Wochen mit phython und bin dabei vor ein paar Tagen auf Twisted gestoßen. Nun möchte ich einen Chat basteln, wobei der Chatserver kein problem ist, dazu gibt es sogar ein Beispiel script auf der twisted homepage.
Und jetzt zu meiner Frage: wie realisiere ich den Client mit twisted?
Da twisted ja event-driven ist weiß ich nicht wie ich die Nachrichten an den Server schicken soll. Mit
kann ich zwar aus der Protocol Classe Nachrichten senden nur finde ich keinen Weg das von außen aus B.z einem Click-Event aufzurufen.
Das geht zwar zimlich einfach mit dem Standard socked modul, aber das muss doch auch mit twisted möglich sein.
Ich hoffe ihr versteht was ich meine und könnt mir helfen

Re: Chatclient mit twisted
Verfasst: Mittwoch 25. Oktober 2006, 14:57
von dev
da_hui hat geschrieben:
Und jetzt zu meiner Frage: wie realisiere ich den Client mit twisted?
Da twisted ja event-driven ist weiß ich nicht wie ich die Nachrichten an den Server schicken soll. Mit
kann ich zwar aus der Protocol Classe Nachrichten senden nur finde ich keinen Weg das von außen aus B.z einem Click-Event aufzurufen.
Du mußt Deiner GUI-Klasse einen Hinweis auf die Protokoll-Klasse mitgeben.
Z.B. in deren
Code: Alles auswählen
def __init__(self, protocol):
self.protocol = protocol
.
Dann kannst Du daraus mittels
das Versenden anwerfen.
Ggf. die Protokoll-Klasse auch um eine write Methode erweitern.
Ciao,
dev
Verfasst: Mittwoch 25. Oktober 2006, 21:46
von da_hui
Danke für die Antwort!
Leider will es bei mir so nicht klappen.
Ich krig immer diesen Fehler:
self.protocol.transport.write(self.t1.GetLineText(0))
AttributeError: 'NoneType' object has no attribute 'write'
Verfasst: Donnerstag 26. Oktober 2006, 14:25
von dev
da_hui hat geschrieben:
self.protocol.transport.write(self.t1.GetLineText(0))
AttributeError: 'NoneType' object has no attribute 'write'
ohne Code von Dir wird das ein Gestochere im Nebel.
Ciao,
dev
Verfasst: Donnerstag 26. Oktober 2006, 21:27
von da_hui
ok also hier ist der code:
Code: Alles auswählen
#client
import socket, wx
from twisted.internet import wxreactor
wxreactor.install()
from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver
class ChatProtocol(LineReceiver):
def connectionMade(self):
print ("Connected to %s." % self.transport.getPeer().host)
def lineReceived(self, line):
print (line + "\n")
class BasicClientFactory(protocol.ClientFactory):
protocol = ChatProtocol
class client_frame(wx.Frame):
def __init__(self, protocol):
self.protocol = protocol
self.s = socket.socket()
self.host = socket.gethostname()
self.port = 1025
wx.Frame.__init__(self, None, title="Chat Client", size=(410, 335))
self.panel = wx.Panel(self)
send_button = wx.Button(self.panel, label= 'Send')
con_button = wx.Button(self.panel, label= 'Connect')
self.Bind(wx.EVT_BUTTON, self.connect, con_button)
self.Bind(wx.EVT_BUTTON, self.send, send_button)
talk_box = wx.TextCtrl(self.panel)
self.t1 = talk_box
contents = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.HSCROLL)
self.t2 = contents
hbox = wx.BoxSizer()
hbox.Add(talk_box, proportion=1, flag=wx.EXPAND)
hbox.Add(send_button, proportion=0, flag=wx.LEFT, border=5)
hbox.Add(con_button, proportion=0, flag=wx.LEFT, border=5)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(hbox, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
vbox.Add(contents, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.LEFT | wx.LEFT, border=5)
self.panel.SetSizer(vbox)
def connect(self, evt):
reactor.connectTCP(self.host, self.port, BasicClientFactory())
reactor.run()
def send(self, evt):
self.protocol.transport.write(self.t1.GetLineText(0))
self.t2.AppendText(self.t1.GetLineText(0) + "\n")
self.t1.Clear()
class App(wx.App):
def OnInit(self):
proto = BasicClientFactory.protocol
frame = client_frame(proto)
self.SetTopWindow(frame)
frame.Show(True)
return True
app = App(redirect = True)
app.MainLoop()
ich denke ich hab's so umgesetzt wie du's beschrieben hast.
Verfasst: Dienstag 7. November 2006, 15:35
von da_hui
hat niemand eine Ahnung

Was hab ich denn im obigen code falsch gemacht?
Verfasst: Sonntag 12. November 2006, 12:15
von dev
da_hui hat geschrieben:hat niemand eine Ahnung

Was hab ich denn im obigen code falsch gemacht?
zum wx Teil kann ich mangels Erfahrung nichts sagen.
Da Du aber Deine BasicClientFactory() sowieso innerhalb Deines client_frame instanziierst, ist eine Übergabe beim client_frame __init__ Blödsinn. Ich ging da von einer anderen Herangehensweise aus.
Dann ist proto = BasicClientFactory.protocol eine Zuweisung der Klasse, nicht eines instanziierten Objekts. [Ist das korrekt ausgedrückt?]
Dein ChatProtocol Objekt wird von der Factory erzeugt, wenn die socket Verbindung hergestellt wurde.
Um also in Deinem Modell zu bleiben, muß das ChatProtocol Objekt sich in der connectionMade Methode bei der der GUI Klasse
melden.
Code: Alles auswählen
class ChatProtocol(LineReceiver):
def connectionMade(self):
print ("Connected to %s." % self.transport.getPeer().host)
self.gui.protocol = self
Hilft Dir das weiter?
Ciao,
dev
Verfasst: Montag 23. Juli 2007, 02:36
von spdy
Auch wenns ein altes thema is fehlen dazu die guten Docus und ich hab im moment ungefair das selbe problem. Was ich persönlich nicht verstehe wie man twisted und wxpython über wxreactor zum miteinander reden bekommt.
so das man ordentlich daten von a nach b und b nach a verschieben kann.
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys,time
from twisted.internet import wxreactor
if sys.modules.has_key('twisted.internet.reactor'):del sys.modules['twisted.internet.reactor']
wxreactor.install()
import wx
wx.SetDefaultPyEncoding("UTF-8")
from twisted.words.protocols import irc
from twisted.internet import reactor
from twisted.internet import protocol
from twisted.python import threadable
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, title="pyChat", size=(800,600))
self.CreateStatusBar()
self.MakeMenuBar()
self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE)
self.splitter.SetMinimumPaneSize(125) #fix my position
self.panel_left = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
self.panel_right = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
self.splitter.SplitVertically(self.panel_left, self.panel_right, sashPosition=125)
self.tree = wx.TreeCtrl(self.panel_left, -1, style=wx.TR_HAS_BUTTONS|wx.TR_DEFAULT_STYLE|wx.SUNKEN_BORDER)
self.workspace = wx.TextCtrl(self.panel_right, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY)
self.chatbox = wx.TextCtrl(self.panel_right,-1,"",style = wx.TE_PROCESS_ENTER)
self.__set_layout()
self.chatbox.Bind(wx.EVT_TEXT_ENTER, self.ChatBox,)
self.workspace.write(u"Welcome to PyChat Alpha\n")
def __set_layout(self):
self.splitter_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.splitter_sizer.Add(self.splitter, 1, wx.ALL|wx.EXPAND, 0)
self.SetSizer(self.splitter_sizer)
self.splitter_sizer.Fit(self)
self.splitter_sizer.SetSizeHints(self)
self.panel_left_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel_left_sizer.Add(self.tree, 1, wx.ALL|wx.EXPAND, 0) #tree window
self.panel_left.SetSizer(self.panel_left_sizer)
self.panel_left.Fit()
self.panel_right_sizer = wx.BoxSizer(wx.VERTICAL)
self.panel_right_sizer.Add(self.workspace, 1, wx.ALL|wx.EXPAND, 0) #main output
self.panel_right_sizer.Add(self.chatbox,0,wx.ALIGN_BOTTOM|wx.EXPAND,0) #chatbox
self.panel_right.SetSizer(self.panel_right_sizer)
self.panel_right.Fit()
self.SetAutoLayout(True)
self.Layout()
def MakeMenuBar(self):
menu = wx.Menu()
menu.Append(5000,"&Connect")
menu.Append(5001,"&Disconnect")
menu.Append(5002,"E&xit")
menubar = wx.MenuBar()
menubar.Append(menu,"&File")
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU,self.OnConnect,id=5000)
self.Bind(wx.EVT_MENU,self.OnDisconnect,id=5001)
self.Bind(wx.EVT_MENU,self.OnExit,id=5002)
def OnExit(self, evt):
self.Close()
def OnConnect(self,evt):
firc = ConnectionFactory()
reactor.connectTCP("localhost",6667,firc)
def OnDisconnect(self,evt):
reactor.stop()
def ChatBox(self,evt):
unicodes = self.chatbox.GetValue()
self.workspace.write(unicodes+"\n") #add to window
self.chatbox.Clear()
class ircCore(irc.IRCClient):
nickname = "changemeplz"
channel = "#testchan"
def connectionMade(self):
irc.IRCClient.connectionMade(self) #call me once
print "[connected at %s]" % time.asctime(time.localtime(time.time()))
def signedOn(self):
self.join(self.channel)
def joined(self,channel):
print "[joined %s]" % channel
class ConnectionFactory(protocol.ClientFactory):
protocol = ircCore
def clientConnectionLost(self,connector,reason):
print "Connection Lost:",reason
connector.connect()
def clientConnectionFailed(self,connector,reason):
print "Connection Failed:",reason
reactor.stop()
class MyApp(wx.App):
def OnInit(self):
frame = MainFrame()
frame.SetSize((800,600))
frame.Show(True)
return True
if __name__ == '__main__':
app = MyApp()
reactor.registerWxApp(app)
reactor.run()
wenn jemand ahnung davon hat wo muss man etwas einfügen damit die kommunikation klappt is im moment ein wenig zu hoch für mich
Verfasst: Mittwoch 25. Juli 2007, 02:06
von spdy
konnte mein problem soweit lösen hab mir ne klasse erstellt
die die ganzen references zu den einzelnen klassen bei der erstellung bekommt
bin nun in der lage alles anzusteuern was ich brauche
was ich mich dabei nu frage ist dies eine gute oder schlechte idee.