【发布时间】:2014-02-20 14:30:22
【问题描述】:
在完成使用它的应用程序的过程中,我仍在努力掌握 Twisted。
我的问题是:
我的应用程序使用 LineReceiver.sendLine 从 Twisted TCP 服务器发送消息。 我想知道sendLine是否成功。
我收集到我需要以某种方式向 sendLine 添加一个成功(和错误?)回调,但我不知道该怎么做。
感谢任何指针/示例
【问题讨论】:
在完成使用它的应用程序的过程中,我仍在努力掌握 Twisted。
我的问题是:
我的应用程序使用 LineReceiver.sendLine 从 Twisted TCP 服务器发送消息。 我想知道sendLine是否成功。
我收集到我需要以某种方式向 sendLine 添加一个成功(和错误?)回调,但我不知道该怎么做。
感谢任何指针/示例
【问题讨论】:
您需要定义“成功”才能对此提出答案。
所有sendLine 所做的立即(可能)是将一些字节添加到发送缓冲区。从某种意义上说,只要它不引发异常(例如,MemoryError 因为您的行太长或TypeError 因为您的行是数字3 而不是实际行)它就成功了。
不过,这并不是一种非常有用的成功。不幸的是,有用的成功更像是“字节被添加到发送缓冲区,发送缓冲区被刷新到套接字,对等方接收到字节,接收应用程序以持久的方式对数据进行操作”。
LineReceiver 中的任何内容都无法告诉您所有这些事情都发生了。标准解决方案是向您的协议添加某种确认:当接收应用程序对数据采取行动时,它会发回一些字节,告诉原始发送者消息已被处理。
你不会得到LineReceiver.sendLine 来帮助你,因为它真正知道如何做的只是以特定格式发送一些字节。您需要更复杂的协议来处理确认。
幸运的是,Twisted 附带了一些。 twisted.protocols.amp 是其中之一:它提供远程方法调用(包含响应)作为基本功能。我发现 AMP 适用于广泛的应用程序,因此推荐用于新开发通常是安全的。它在很大程度上取代了旧的twisted.spread(又名“PB”),后者还提供远程方法调用和远程对象引用(因此更复杂——根据我的经验,比大多数应用程序需要的更复杂)。还有一些更标准的选项:例如,Twisted Web 包含一个 HTTP 实现(您可能知道,HTTP 擅长请求/响应样式的交互)。
【讨论】:
IProducer 和IConsumer 的前者。如果您编写生产者并将其注册到传输(即消费者),则传输将在用户空间缓冲区“满”时调用您的生产者pauseProducing,当用户空间缓冲区为“空”时调用resumeProducing。这是你想要的信息。没有公共 API 可以更直接地获取信息。
sendLine 数据到达您的对等点,即使它已经跨越内核/用户空间边界。如果您的连接异常终止(您的外部主机断开您的连接,您的路由器爆炸,世界末日),很可能最后几条“成功”传输的线路仍然会丢失。知道为什么你想知道成功/失败会很有用;可能还有其他更适合您的用例的信息。