Reputation: 702
I have a very simple client and server (both written in Python using Twisted). The server loops and sends a message out to the client every X millis. The server is running on my Raspberry Pi and my client is on my laptop, both of which are connected to my home network.
Server:
from twisted.internet import reactor, protocol
from twisted.protocols.basic import NetstringReceiver
from twisted.internet.task import LoopingCall
from datetime import datetime
class MyProtocol(NetstringReceiver):
def connectionMade(self):
self.factory.myOnlyProtocol = self
def connectionLost(self, reason):
self.factory.myOnlyProtocol = None
class MyFactory(protocol.ServerFactory):
protocol = MyProtocol
def __init__(self):
self.myOnlyProtocol = None
self.timeStart = datetime.now()
self.loop = LoopingCall(self.sendSomethingToClient)
self.loop.start(0.1)
print 'Server running'
def sendSomethingToClient(self):
if self.myOnlyProtocol is not None:
millis = (datetime.now() - self.timeStart).microseconds / 1000
print 'Since message sent: {}ms'.format(millis)
self.timeStart = datetime.now()
self.myOnlyProtocol.sendString('something')
reactor.listenTCP(1079, MyFactory())
reactor.run()
Client:
from twisted.internet import reactor, protocol
from twisted.protocols.basic import NetstringReceiver
from datetime import datetime
class MyProtocol(NetstringReceiver):
def __init__(self):
self.timeStart = datetime.now()
def connectionMade(self):
print 'Connected to server'
def stringReceived(self, data):
millis = (datetime.now() - self.timeStart).microseconds / 1000
print 'Since last message: {}ms'.format(millis)
self.timeStart = datetime.now()
class MyFactory(protocol.ClientFactory):
protocol = MyProtocol
reactor.connectTCP('192.168.0.7', 1079, MyFactory())
reactor.run()
This works fine until I start sending the messages every 100ms or so, at which point the client starts receiving the messages more sporadically. This is what I see when I run the scripts:
Server:
Since message sent: 99ms
Since message sent: 99ms
Since message sent: 99ms
Since message sent: 99ms
Since message sent: 99ms
Since message sent: 99ms
Client (messages every 1ms):
Since last message: 181ms
Since last message: 0ms
Since last message: 147ms
Since last message: 0ms
Since last message: 188ms
Since last message: 1ms
If I try to send the messages even faster, it just exacerbates the problem:
Client (messages every 0.5ms):
Since last message: 157ms
Since last message: 0ms
Since last message: 0ms
Since last message: 1ms
Since last message: 154ms
Since last message: 0ms
Since last message: 0ms
Since last message: 0ms
I'm not sure if it's some weirdness with Twisted sending messages, or if it's my home network, or how to even check which it is. Any ideas?
Upvotes: 2
Views: 455
Reputation: 31860
When you care about write-to-read latency on TCP connections, your first step should be to disable Nagle's algorithm by doing self.transport.setTcpNoDelay(True)
in both the client's and the server's connectionMade
methods.
If you want to measure whether it is your network connection or Twisted, looking carefully at Wireshark logs collected both on the client and the server and comparing them with your processes' logs should give you an idea of when the traffic is actually sent and received versus when it is processed by the application layer.
If you care a lot about latency, LoopingCall.withCount
will give you a better idea if other things are blocking the mainloop and causing the measurement in your timer itself to be inaccurate.
Upvotes: 4