Python, Twisted

Stiahnite si na začiatok virtuálny stroj tu. (Ak máte z minulej hodiny tak nemusíte.)

Twisted
Twisted is an open source, event-driven networking engine written in Python.
Twisted supports many common transport and application layer protocols, including TCP, UDP, SSL/TLS, HTTP, IMAP, SSH, IRC, and FTP. Like the language in which it is written, it is “batteries-included”; Twisted comes with client and server implementations for all of its protocols, as well as utilities that make it easy to configure and deploy production-grade Twisted applications from the command line.
Official site.
V linuxe nainštalujeme tento framework takto: sudo apt-get install python-twisted

Simple Chat
Vytvoríme si jednoduchú chatovaciu aplikáciu, ktorá bude pozostávať z klientskej časti a z časti, ktorá pobeží na servri.

Server Site
Najprv si nadefinujeme protokol, ktorým budeme komunikovať. Bude veľmi jednoduchý, všetko čo mu príde odošle pripojeným chaterom okrem seba.

class MyProtocol(LineReceiver):

    def lineReceived(self, line):
        print line
        for online in self.factory.online:
            if not online is self:
                online.sendLine(line)

    def connectionMade(self):
        self.factory.online.append(self)
        print self.transport.getHost()

    def connectionLost(self, reason):
        self.factory.online.remove(self)

Teraz si vytvoríme Factory, ktorá si bude pamätať pripojených chaterov.

class MyFactory(ServerFactory):
    protocol = MyProtocol

    def __init__(self):
        self.online = []

Ešte kód pre spúštanie

application = service.Application("chatserver")
internet.TCPServer(1234,MyFactory()).setServiceParent(application)

Client Site
Teraz si ešte vytvoríme klienta. Klientská aplikácia bude postavená na gtk gui. Taktiež si najprv nadefinujeme protokol.

class MyProtocol(LineReceiver):
    def lineReceived(seld, line):
        gui.set_chat(line)

    def connectionMade(self):
        print "Connection made"
        gui.set_connected("Connected")

    def connectionLost(self, reason):
        print "Connection Lost"
        gui.set_connected("Connection Lost")

Ako vidíme, v protokole sa odvolávame na dve metódy z gui prostredia. Teda teraz si vytvoríme gui.

class Window(gtk.Window):
    def __init__ (self):
        super(Window, self).__init__()
        self.set_default_size(400, 300)
        self.set_title("Simple Twisted chat")

        self.vbox = gtk.VBox()

        self.label = gtk.Label("Waiting...")
        self.entry = gtk.Entry()
        self.textview = gtk.TextView()
        self.textbuffer = self.textview.get_buffer()
        self.textbuffer.set_text("")
        self.textview.set_editable(False)
        self.textview.set_left_margin(5)
        self.textview.set_cursor_visible(False)
        
        
        
        self.scroll = gtk.ScrolledWindow()
        self.scroll.add(self.textview)
        self.scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)

        self.vbox.pack_start(self.label)
        self.vbox.pack_start(self.scroll)
        self.vbox.pack_start(self.entry)

        self.add(self.vbox)

        self.entry.connect("activate", self.on_clicked)
        self.connect("destroy", lambda x: reactor.stop())

        self.show_all()
        self.show()
        self.entry.grab_focus()

    def on_clicked(self, widget):
        if self.entry.get_text():
                factory.instance.sendLine(self.entry.get_text()) 
                end_iter = self.textbuffer.get_end_iter()
                self.textbuffer.insert(end_iter,"Me:  "+self.entry.get_text()+"\n")
                self.entry.set_text("")
                adj = self.scroll.get_vadjustment()
                adj.set_value(adj.upper - adj.page_size)

    def set_connected(self, string):
        self.label.set_text(string)

    def set_chat(self, string):
        end_iter = self.textbuffer.get_end_iter()
        self.textbuffer.insert(end_iter,"#:  "+string+"\n")
        adj = self.scroll.get_vadjustment()
        adj.set_value(adj.upper - adj.page_size)

Nezabudnime ešte na Factory pre klienta. Tá nebude vpodstate ničím výnimočná.

class MyFactory(ClientFactory):
    protocol = MyProtocol

    def buildProtocol(self, addr):
        self.instance = self.protocol()
        return self.instance

A ešte si vytvoríme main, kde celú aplikáciu spustíme.

if __name__ == '__main__':
    gui = Window()
    from twisted.internet import reactor
    factory = MyFactory()
    reactor.connectTCP('localhost', 1234, factory)
    reactor.run()

Celý kód na stiahnutie: chatserver.py, chatclient.py.
Tu je server, ktorý pri zadaní správy typu NAME {meno} si uloží meno a potom v klientovi zobrazuje, kto správu odoslal. TU