Making Twisted Python simple client server example to work - python

I am new to Twisted python (Twisted 12.x, python 2.6.x, unfortunately I have to use the older version), and I am running client/server in which the server echoes a simple message from the client (example from chap 2 of Twisted O'reilly book) I am running server in a terminal, and then client in a separate terminal. But client and server are stuck (not returning). What is failing?
server:
from twisted.internet import protocol, reactor
class Echo(protocol.Protocol):
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(protocol.Factory):
def buildProtocol(self, addr):
return Echo()
reactor.listenTCP(50000, EchoFactory())
reactor.run()
client:
from twisted.internet import reactor, protocol
class EchoClient(protocol.Protocol):
def connectionMade(self):
self.transport.write("Hello, world!")
def dataReceived(self, data):
print "Server said:", data
self.transport.loseConnection()
class EchoFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return EchoClient()
def clientConnectionFailed(self, connector, reason):
print "Connection failed."
reactor.stop()
def clientConnectionLost(self, connector, reason):
print "Connection lost."
reactor.stop()
reactor.connectTCP("localhost", 50000, EchoFactory())
reactor.run()

Your dataReceived, clientConnectionFailed, and clientConnectionLost methods are not indented, which means they are just free functions that are never being called, rather than overriding methods on Protocol or ClientFactory. So your client code will get the default dataReceived implementation, which is "do nothing".
Also, by the way, Python 2.6 is out of security support and will not receive updates. Please upgrade to version 2.7.9 at least. You should also upgrade to a recent version of Twisted, especially if this is for new code; there is really no legitimate reason to use software this old; it is dangerous and irresponsible to do so.

Related

Python - Twisted client - check protocol.transport connection in ping loop

I'm creating TCP client socket with Twisted. I need to check connection status in a loop interval in connectionMade method.
from twisted.internet import reactor, protocol
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
while not thread_obj.stopped.wait(10):
print ('ping')
self.transport.write(b'test') # Byte value
For check connection losing, i manually disconnect my network And I checked some variables after that as bellow:
print (self.connected)
print (self.transport.connector.state)
print (self.transport.connected)
print (self.transport.reactor.running)
print (self.transport.socket._closed)
print (self.factory.protocol.connected)
print (self._writeDissconnected)
But any variables value didn't change after disconnecting my network :(
My question is: which variables will be set when the connection lost? I mean how can i check the connection status and if it's disconnect, how can i reconnect that?
override connectionLost method to catch disconnection.
to official docs
Edit about reconnection:
Reconnection mostly is a logical decision. You may want to add logic between 'connectionLost' and 'reconnect'.
Anyway,
You can use ReconnectingClientFactory for better code.
ps: using factory pattern at reconnection is best way to keep code clean and smart.
class MyEchoClient(Protocol):
def dataReceived(self, data):
someFuncProcessingData(data)
self.transport.write(b'test')
class MyEchoClientFactory(ReconnectingClientFactory):
def buildProtocol(self, addr):
print 'Connected.'
return MyEchoClient()
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)

Twisted - I need to periodically connect/disconnect a client connection

I have a twisted tcp client that I would like to periodically cause to connect, receive a stream of date for n seconds, then disconnect.
After disconnecting n seconds would elapse before the process started over again.
Below is a very abbreviated extract of the code I've tried so far.
When I run the code the reactor.stop() is issued, and after the sleep elapses I get a twisted.internet error 'ReactorAlreadyRunning' when the reactor.run() is invoked in startClientConnection()
I'm a raw novice at using twisted and I'm not sure what I've done wrong. Any help will be much appreciated.
class TCPClientFactory(ReconnectingClientFactory)
def startedConnecting(self, connector):
pass
def buildProtocol(self, addr):
self.resetDelay()
return MsgProcessor()
def clientConnectionLost(self, connector, reason):
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
def clientConnectionFailed(self, connector, reason):
ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
class mainClass(object):
def __init__(self):
...
def startClientConnection(self):
reactor.connectTCP(host, port, TCPClientFactory())
reactor.callLater(60, self.periodic_connect_manager)
reactor.run()
def periodic_connect_manager(self):
reactor.stop()
time.sleep(60)
self.startClientConnection()
reactor.run() should be run only once.
from twisted.internet import task, reactor
def connect():
do_connect()
reactor.callLater(60, disconnect) # disconnect in a minute
task.LoopingCall(connect).start(120) # call connect() every 2 minutes
reactor.run()

Python Chat Client not Remaining Open

I have recently started developing a server-client chat protocol for learning purposes (later I would like to do more with this communication, but for now this suffices. Needless to say, I am still early into the learning phase of this portion of Python, but I have modified some examples to a server and a client that I found online. The communication works well from what I've seen so far, but I have to relaunch the client every time I want to send a message to the server.
Here is the code:
server:
from twisted.internet import reactor, protocol
from twisted.protocols import basic
class Echo(protocol.Protocol):
def dataReceived(self, data):
"As soon as any data is received, write it back."
self.transport.write(data)
class MyChat(basic.LineReceiver):
def connectionMade(self):
print "Got new client!"
self.factory.clients.append(self)
def connectionLost(self, reason):
print "Lost a client!"
self.factory.clients.remove(self)
def dataReceived(self, data):
print "received", repr(data)
for c in self.factory.clients:
c.message(data)
def message(self, message):
self.transport.write(message + '\n')
def main():
"""This runs the protocol on port 8000"""
factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []
reactor.listenTCP(8000,factory)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
client:
from twisted.internet import reactor, protocol
# a client protocol
class EchoClient(protocol.Protocol):
"""Once connected, send a message, then print the result."""
def connectionMade(self):
self.transport.write("hello, world!")
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Server said:", data
self.transport.loseConnection()
def connectionLost(self, reason):
print "connection lost"
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def clientConnectionFailed(self, connector, reason):
connector.connect()
print "Connection failed - goodbye!"
reactor.stop()
def clientConnectionLost(self, connector, reason):
connector.connect()
print "Connection lost - goodbye!"
reactor.stop()
# this connects the protocol to a server runing on port 8000
def main():
f = EchoFactory()
client = EchoClient()
reactor.connectTCP("localhost", 8000, f)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
What am I forgetting to add so that I can have multiple clients connected to the server and stay connected?
I looked here and here (the first one seems to be the same type of question) but I'm still confused as to how to fix this issue. Any suggestions are appreciated. Thanks!

Twisted client connection lost

I have a very simple client program:
class EchoClient(Int32StringReceiver):
def connectionMade(self):
print 'connection made.'
str = "<request><commands><dbtest /></commands></request>"
self.sendString(str)
print 'message sent'
def stringReceived(self, line):
print "receive:", line
self.transport.loseConnection()
class EchoClientFactory(ClientFactory):
def buildProtocol(self, addr):
return EchoClient()
def clientConnectionFailed(self, connector, reason):
print 'connection failed:', reason.getErrorMessage()
reactor.stop()
def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()
def main():
factory = EchoClientFactory()
reactor.connectTCP('localhost', 3604, factory)
reactor.run()
I connect to a Java service implemented in Apache CXF (and some proprietary company code).
It connects fine, sends the message, the service receives it and produces a response.
Sadly, this client does not wait for the server to produce its message, but disconnects right after the message is sent. So the output I get from the client is:
connection made.
message sent
connection lost: Connection was closed cleanly.
And of course the Java service throws an exception complaining about the connection being already closed.
What am I missing here?
EDIT: adding this line shows that the message is received, as it prints it correctly:
def dataReceived(self, data):
print(data)
self.transport.loseConnection()
So the real problem is that the stringReceived() function is not called. Maybe I have the wrong signature for this function?
I'm onto something here:
def lengthLimitExceeded(self, length):
print('length limit exceeded: {}'.format(length))
prints:
length limit exceeded: 2147483793
length limit exceeded: 2147483793
which is 0x80000091, so it seems that our propietary API is implementing the NString protocol in a strange way (maybe uses the MSB for something else).

Python Twisted Client

I have this simple Twisted Client which connects to a Twisted server & queries an index.
If you see fn. connectionMade() in class SpellClient, the query is hard-coded. Did that for testing purposes. How would one pass this query from outside to this class?
The code -
from twisted.internet import reactor
from twisted.internet import protocol
# a client protocol
class SpellClient(protocol.Protocol):
"""Once connected, send a message, then print the result."""
def connectionMade(self):
query = 'abased'
self.transport.write(query)
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Server said:", data
self.transport.loseConnection()
def connectionLost(self, reason):
print "connection lost"
class SpellFactory(protocol.ClientFactory):
protocol = SpellClient
def clientConnectionFailed(self, connector, reason):
print "Connection failed - goodbye!"
reactor.stop()
def clientConnectionLost(self, connector, reason):
print "Connection lost - goodbye!"
reactor.stop()
# this connects the protocol to a server runing on port 8000
def main():
f = SpellFactory()
reactor.connectTCP("localhost", 8090, f)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
Protocols, like SpellClient, have access to their factory as self.factory.
...so there would be a number of ways to do this, but one way would be to create another method on SpellFactory, such as setQuery, and then access that from the client...
#...in SpellFactory:
def setQuery(self, query):
self.query = query
#...and in SpellClient:
def connectionMade(self):
self.transport.write(self.factory.query)
...so in main:
f = SpellFactory()
f.setQuery('some query')
...
...or you could just create an _init_ method for SpellFactory, and pass it in there.

Categories