简体   繁体   English

从Twisted服务器接收消息时滞后

[英]Lag in receiving messages from Twisted server

I have a very simple client and server (both written in Python using Twisted). 我有一个非常简单的客户端和服务器(都使用Twisted编写的Python)。 The server loops and sends a message out to the client every X millis. 服务器循环并每X毫秒向客户端发送一条消息。 The server is running on my Raspberry Pi and my client is on my laptop, both of which are connected to my home network. 服务器在我的Raspberry Pi上运行,我的客户端在我的笔记本电脑上,两者都连接到我的家庭网络。

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. 这工作正常,直到我开始每100ms左右发送一次消息,此时客户端开始偶尔开始接收消息。 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): 客户端(每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): 客户端(每隔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. 我不确定Twisted发送消息是否有些奇怪,或者它是否是我的家庭网络,或者如何检查它是什么。 Any ideas? 有任何想法吗?

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. 当您关心TCP连接上的写入读取延迟时,您的第一步应该是通过在客户端和服务器的connectionMade方法中执行self.transport.setTcpNoDelay(True)来禁用Nagle的算法

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. 如果要测量它是网络连接还是Twisted,请仔细查看在客户端和服务器上收集的Wireshark日志,并将它们与流程日志进行比较,这样可以让您了解实际发送和接收流量的时间。当它由应用层处理时。

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. 如果你非常关心延迟, LoopingCall.withCount会让你更好地了解其他东西是否阻塞了主循环并导致你的计时器本身的测量结果不准确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM