Twisted transport.write

6 投票
3 回答
7415 浏览
提问于 2025-04-16 03:34

有没有办法让 self.transport.write(response) 立即写入连接,这样下一次调用 self.transport.write(response) 时就不会被合并到同一次调用中。

我们有一个客户使用的旧软件,我们无法修改,它在第一次请求后开始读取,然后再开始读取。我的问题是,twisted 将两次写入合并在一起,这样会导致客户端出现问题。我尝试过查看 deferreds,但我觉得在这种情况下可能没有帮助。

示例:

self.transport.write("|123|") # amount of messages to follow 
a loop to generate next message
self.transport.write("|message 1 text here|")

期望的结果:

|123|
|message 1 text here|

实际结果:

|123||message 1 text here|

3 个回答

0

也许你可以把你的协议注册为一个数据拉取的生产者,交给传输层来处理。

self.transport.registerProducer(self, False)

然后在你的协议里创建一个写入方法,这个方法的工作是把数据暂时存起来,直到传输层调用你的协议中的resumeProducing方法,逐个取出这些数据。

def write(self, data):
    self._buffers.append(data)

def resumeProducing(self):
    data = self._buffers.pop()
    self.transport.write(data)
0

你能告诉我你正在使用哪种传输方式吗?对于大多数实现来说,通常的做法是:

 def write(self, data):
        if data:
            if self.writeInProgress:
                self.outQueue.append(data)
            else:
                ....

根据这些细节,写入函数的行为可以根据需要进行调整。

2

我遇到了一个和这个问题有点相关的情况,使用的是较旧的Python 2.6版本。我正在和一个主机通信,它期待先收到一个单独的确认字符,然后再接收一个单独的数据缓冲区,但实际上它们是一起发送过来的。而且,这还是一个TLS连接。不过,如果你直接引用这个socket,你可以这样调用sendall():

self.transport.write(Global.ACK)

变成:

self.transport.getHandle().sendall(Global.ACK)

...这样应该就能正常工作了。在Python 2.7和Twisted框架下的X86系统上似乎没有这个问题,问题只出现在使用SHEEVAPlug ARM处理器的Python 2.6上。

撰写回答