Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
fw:twisted [2009/11/02 18:38] alfred |
fw:twisted [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== Twisted ====== | ====== 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. | 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. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| Línea 9: | Línea 13: | ||
| * ''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.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.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). | + | * ''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. \\ \\ | 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''. \\ \\ | ''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). 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. | + | 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 === | === Ejemplos === | ||
| Línea 32: | Línea 36: | ||
| reactor.run() | reactor.run() | ||
| </code> | </code> | ||
| - | Este otro ejemplo crea un servidor accesible desde telnet que devuelve y recibe textos: | + | Este otro ejemplo crea un servidor accesible desde telnet que devuelve y recibe textos. El ServerFactory es creada por nosotros y define los protocolos |
| <code python> | <code python> | ||
| from twisted.internet import reactor | from twisted.internet import reactor | ||
| Línea 63: | Línea 67: | ||
| headlines = ["Area man says pie is delicious.", "USA Declares War on Moon", "Python is Great!"] | headlines = ["Area man says pie is delicious.", "USA Declares War on Moon", "Python is Great!"] | ||
| factory = NewsProtocolFactory(headlines) | factory = NewsProtocolFactory(headlines) | ||
| + | reactor.listenTCP(14000, factory) | ||
| + | reactor.run() | ||
| + | </code> | ||
| + | Sencillo servidor de chat: | ||
| + | <code python> | ||
| + | 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.listenTCP(14000, factory) | ||
| reactor.run() | reactor.run() | ||
| Línea 68: | Línea 130: | ||
| ===== Otros ===== | ===== Otros ===== | ||
| + | |||
| ==== Links ==== | ==== Links ==== | ||
| + | * [[http://twistedmatrix.com/trac/|Pagina del proyecto]] | ||
| + | * [[http://www.zope.org/Products/ZopeInterface/|A partir de //x// versión tiene una dependencia a esta librería.]] | ||
| * [[http://twistedmatrix.com/documents/current/api|API]] | * [[http://twistedmatrix.com/documents/current/api|API]] | ||