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