Herramientas de usuario

Herramientas del sitio


fw:twisted

¡Esta es una revisión vieja del documento!


Tabla de Contenidos

Twisted

Es un framework para la programación de software en red, soporta un gran número de protocolos y tipos de sockets y está basado en la implementación de eventos. Esto es, el desarrollador escribe pequeños callbacks que son llamados por el framework.

Básico

  • twister.internet.reactor: Un reactor es el bucle de eventos dentro de Twisted, el que dirige la aplicación dentro de este Framework. Provee helpers para el trabajo con networking, threading, eventos, dispatching (eventos en background)…
  • twister.internet.BaseProtocol: Una implementación base de un twister.internet.Protocol, es decir, una estructura de funcionamiento.
  • twister.internet.Factory: Es el elemento a partir del que se produce, se crea o se utiliza un protocolo, pueden haber de cliente (ClientFactory) o de servidor (ServerFactory).


Un Protocol representa una conexión, si se desarrolla un server y se conectan cien clientes se crearán cien instancias de esta clase y desaparecerán cuando el cliente se desconecte. Un protocolo provee la funcionalidad básica para la comunicación y provee distintos métodos que al heredar de esta clase pueden ser sobreescritos y utilizarlos. Por ejemplo, en twisted.protocols encontramos gran variedad de protocolos (los más sencillos en twisted.protocols.basics) que podemos utilizar heredando de estas clases y sobreescribiendo sus métodos.

ServerFactory es el encargado de crear los protocolos, cada vez que un cliente conecte se instancia un objeto Protocol.

Los reactor son el motor de los programas en Twisted, existe un reactor por defecto (que podemos activar o desactivar con sus métodos on y off). Es el que configura las Factory para que acepten las nuevas conexiones que estos le pasan ya que estos son los que escuchan por los puertos.

Ejemplos

Por ejemplo, en el siguiente código se crea un protocolo heredando de la clase twisted.internet.protocol.Protocol, este es usado por una factoria de servidor como TCP:

from twisted.internet.protocol import Protocol, ServerFactory
from twisted.internet import reactor
 
class BasicProtocol(Protocol):
    def connectionMade(self):
        print "New Connection."
        self.transport.loseConnection()
 
factory = ServerFactory()
factory.protocol = BasicProtocol
reactor.listenTCP(14000, factory)
reactor.run()

Este otro ejemplo crea un servidor accesible desde telnet que devuelve y recibe textos. El ServerFactory es creada por nosotros y define los protocolos

from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
 
class NewsProtocol(LineOnlyReceiver):
    def connectionMade(self):
        print "New connection from "+self.transport.getPeer().host
        self.sendLine("Do you want the news? (type YES or NO)")
 
    def connectionLost(self, reason):
        print "Lost connection from "+self.transport.getPeer().host
 
    def lineReceived(self, line):
        if line=="YES":
            for headline in self.factory.headlineList:
                self.sendLine("HEADLINE: "+headline)
            self.sendLine("Do you want the news? (type YES or NO)")
        elif line=="NO":
            self.transport.loseConnection()
        else:
            self.sendLine("Unknown Command. Do you want the news? (type YES or NO)")
 
class NewsProtocolFactory(ServerFactory):
    protocol = NewsProtocol
    def __init__(self, headlines):
        self.headlineList = headlines
 
headlines = ["Area man says pie is delicious.", "USA Declares War on Moon", "Python is Great!"]
factory = NewsProtocolFactory(headlines)
reactor.listenTCP(14000, factory)
reactor.run()

Sencillo servidor de chat:

from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory 
from twisted.protocols.basic import LineOnlyReceiver 
 
class ChatProtocol(LineOnlyReceiver): 
 
    name = "" 
 
    def getName(self): 
        if self.name!="": 
            return self.name 
        return self.transport.getPeer().host 
 
    def connectionMade(self): 
        print "New connection from "+self.getName() 
        self.sendLine("Welcome to my my chat server.") 
        self.sendLine("Send '/NAME [new name]' to change your name.") 
        self.sendLine("Send '/EXIT' to quit.") 
        self.factory.sendMessageToAllClients(self.getName()+" has joined the party.") 
        self.factory.clientProtocols.append(self)
 
    def connectionLost(self, reason): 
        print "Lost connection from "+self.getName() 
        self.factory.clientProtocols.remove(self) 
        self.factory.sendMessageToAllClients(self.getName()+" has disconnected.") 
 
    def lineReceived(self, line): 
        print self.getName()+" said "+line 
        if line[:5]=="/NAME": 
            oldName = self.getName() 
            self.name = line[5:].strip() 
            self.factory.sendMessageToAllClients(oldName+" changed name to "+self.getName()) 
        elif line=="/EXIT": 
            self.transport.loseConnection() 
        else: 
            self.factory.sendMessageToAllClients(self.getName()+" says "+line) 
 
    def sendLine(self, line): 
        self.transport.write(line+"\r\n") 
 
class ChatProtocolFactory(ServerFactory): 
 
    protocol = ChatProtocol 
 
    def __init__(self): 
        self.clientProtocols = [] 
 
    def sendMessageToAllClients(self, mesg): 
        for client in self.clientProtocols:
            client.sendLine(mesg) 
 
print "Starting Server"
factory = ChatProtocolFactory()
reactor.listenTCP(14000, factory)
reactor.run()

Otros

fw/twisted.1257239420.txt.gz · Última modificación: 2020/05/09 09:24 (editor externo)