Write a simple Web client using the Python twisted framework

Source: Internet
Author: User
Protocol
Like a server, it is implemented by this class. Let's look at a short routine:

From twisted.internet.protocol import protocolfrom sys import stdoutclass Echo (protocol):  def datareceived (self, Data):    stdout.write (data)

In this program, it is simply the output of the obtained data to the standard output to display, there are many other events did not make any response, the following
There is an example of a response to other events:

From Twisted.internet.protocol import Protocolclass welcomemessage (protocol):  def connectionmade (self):    Self.transport.write ("Hello server, I am the client!/r/n")    self.transport.loseConnection ()

This protocol connects to the server, sends a greeting message, and then closes the connection.
Connectionmade events are usually triggered when an event that establishes a connection occurs. The Connectionlost event function is triggered when the connection is closed

Simple single-User client (Single-use clients)
In many cases, protocol only needs to connect to the server once, and the code is simply to get an instance of the Protocol connection. In
In this case, Twisted.internet.protocol.ClientCreator provides an appropriate API

From twisted.internet import reactorfrom twisted.internet.protocol Import protocol, Clientcreatorclass Greeter ( Protocol):  def sendMessage (self, msg):    self.transport.write ("MESSAGE%s/n"% msg) def gotprotocol (p):  P.sendmessage ("Hello")  reactor.calllater (1, P.sendmessage, "This was sent in a second")  Reactor.calllater (2, p.transport.loseconnection) C = Clientcreator (reactor, Greeter) c.connecttcp ("localhost", 1234). Addcallback ( Gotprotocol)


Clientfactory (Customer Factory)
Clientfactory is responsible for creating the protocol and returning the connection state of the related event. This allows it to do something like a connection error and then
Reconnect to the thing. Here is a simple example of clientfactory using the Echo protocol and printing the current connection state

From Twisted.internet.protocol import protocol, clientfactoryfrom sys import stdoutclass Echo (protocol):  def DataReceived (self, data):    stdout.write (data) class Echoclientfactory (clientfactory):  def startedconnecting (Self, connector):    print ' Started to connect. '    def buildprotocol (self, addr):    print ' Connected. '    Return Echo ()    def clientconnectionlost (self, connector, reason):    print ' Lost connection. Reason: ', Reason    def clientconnectionfailed (self, connector, Reason):    print ' Connection failed. Reason: ', Reason

To connect Echoclientfactory to the server, you can use the following code:

From twisted.internet import reactorreactor.connecttcp (host, Port, Echoclientfactory ()) Reactor.run ()

Note: clientconnectionfailed is called when connection cannot be established, Clientconnectionlost is called when the connection is closed, and the two are different.


Reconnection (Reconnect)
Many times, client connections can often be disconnected due to network errors. A method of re-establishing a connection is to call when the connection is broken

Connector.connect () method.

From Twisted.internet.protocol import Clientfactoryclass echoclientfactory (clientfactory):  def Clientconnectionlost (self, connector, reason):    connector.connect ()

Connector is an interface between connection and protocol that is passed as the first parameter to Clientconnectionlost,

Factory can call the Connector.connect () method to reconnect
However, many programs use the Reconnectingclientfactory function instead of this when the connection fails and the connection is disconnected to reconnect.

function, and try to reconnect again. Here is an example of ECHO protocol using reconnectingclientfactory:

From Twisted.internet.protocol import protocol, reconnectingclientfactoryfrom sys import stdoutclass Echo (protocol):  def datareceived (self, data):    stdout.write (data) class Echoclientfactory (reconnectingclientfactory):  def startedconnecting (self, connector):    print ' Started to connect. '  def buildprotocol (self, addr):    print ' Connected. '    print ' resetting reconnection delay '    self.resetdelay ()    return Echo ()  def clientconnectionlost (self, Connector, reason):    print ' Lost connection. Reason: ', Reason    reconnectingclientfactory.clientconnectionlost (self, connector, Reason)  def Clientconnectionfailed (self, connector, reason):    print ' Connection failed. Reason: ', Reason    reconnectingclientfactory.clientconnectionfailed (self, Connector,reason)


A Higher-level Example:irclogbot
All the examples above are very simple, here is a more complicated example from the Doc/examples directory

# twisted Importsfrom twisted.words.protocols import ircfrom twisted.internet import reactor, Protocolfrom Twisted.python Import log# System Importsimport time, Sysclass messagelogger: "" "an independent logger class (because s  Eparation of application and protocol logic is a good thing).    "" "Def __init__ (self, file): self.file = File def log (self, message):" "" Write a message to the file. ""     timestamp = Time.strftime ("[%h:%m:%s]", Time.localtime (Time.time ())) Self.file.write ('%s%s/n '% (timestamp, message)) Self.file.flush () def close (self): Self.file.close () class Logbot (IRC).  ircclient): "" "A Logging IRC bot." "" " Nickname = "Twistedbot" def Connectionmade (self): IRC. Ircclient.connectionmade (self) Self.logger = Messagelogger (open (Self.factory.filename, "a")) Self.logger.log ("[Conn Ected at%s] "% Time.asctime (Time.localtime (Time.time ())) def connectionlost (self, Reason): IRC. Ircclient.connectionlost (self, Reason) Self.logger.log ("[diSconnected at%s] "% Time.asctime (Time.localtime (Time.time ())) Self.logger.close () # Callbacks for events    def Signedon (self): "" "Called when Bot had succesfully signed on to server." "     Self.join (Self.factory.channel) def joined (self, Channel): ' "" This'll get called when the bot joins the channel. "" Self.logger.log ("[I had joined%s]"% channel) def privmsg (self, user, channel, msg): "" The This'll get called whe    n the bot receives a message. "" user = User.split ('! ', 1) [0] Self.logger.log ("<%s>%s"% (user, msg)) # Check to see if they ' re sending me a P Rivate message if channel = = Self.nickname:msg = "It isn ' t nice to whisper!      Play Nice with the group. " Self.msg (user, MSG) return # Otherwise Check to see if it was a message directed at me if Msg.startswith (self.ni Ckname + ":"): Msg = "%s:i am a log bot"% User self.msg (channel, msg) Self.logger.log ("<%s>%s"% ( Self.nickname, msg)) def ACTIOn (self, user, channel, msg): "" This would get called when the bot sees someone does an action. "" user = User.split ('! ', 1) [0] Self.logger.log ("*%s%s"% (user, msg)) # IRC callbacks def irc_nick (self, prefix, para    ms): "" "Called when an IRC user changes their nickname." "" Old_nick = Prefix.split ('! ') [0] New_nick = params[0] Self.logger.log ("%s is now known as%s"% (Old_nick, New_nick)) Class Logbotfactory (protocol .  clientfactory): "" "A Factory for Logbots.  A new Protocol instance would be created each time we connect to the server. "" "# The class of the Protocol to build when new connection is made protocol = Logbot def __init__ (self, channel, file Name): Self.channel = Channel Self.filename = filename def clientconnectionlost (self, connector, reason): "" "If    We get disconnected, reconnect to server. "" " Connector.connect () def clientconnectionfailed (self, connector, reason): print "Connection failed:", reason reactor . Stop () if __name__ = = ' __main__ ': # Initialize logging log.startlogging (sys.stdout) # Create factory protocol and application F = logbotfactor Y (sys.argv[1], sys.argv[2]) # Connect factory to this host and Port reactor.connecttcp ("irc.freenode.net", 6667, F) # R Un bot reactor.run ()

The irclogbot.py connects to the IRC server, joins a channel, and records all of the communication information in the file, indicating that the logic of the connection level at which the disconnection is being reconnected and the persistence data is stored in the factory.

Persistent Data in the Factory
Because protocol is rebuilt each time the connection is made, the client needs to record data in some way to ensure persistence. It's like a log robot. He needs to know that the channel is landing and landing somewhere.

From twisted.internet import protocolfrom twisted.protocols import Ircclass Logbot (IRC. Ircclient):  def connectionmade (self):    IRC. Ircclient.connectionmade (self)    Self.logger = Messagelogger (open (Self.factory.filename, "a"))    Self.logger.log ("[connected at%s]"%            time.asctime (Time.localtime (Time.time ()))    def-Signedon (self):    Self.join (Self.factory.channel)  class logbotfactory (protocol. Clientfactory):    protocol = Logbot    def __init__ (self, Channel, filename):    Self.channel = Channel    Self.filename = filename

When protocol is created, Factory will get a reference to an instance of himself. Then, it is possible to have his attributes in the factory.

For more information:
The Protocol class described in this document is a subclass of Iprotocol, Iprotocol convenient to use in a large number of twisted applications. To learn the full Iprotocol interface, please refer to the API documentation Iprotocol.
The Trasport attribute used in some examples of this document provides the Itcptransport interface, to learn the full interface, refer to the API documentation Itcptransport
An interface class is a way to specify the methods and properties of an object and their representation. Reference components:interfaces and Adapters documentation

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.