我正在使用Twisted + AMP在服务器和客户端(两者都是Python)之间进行通信,完全在我的控制之下。我的消息通常很短,但有时参数可能会超过64K的限制。有什么办法可以优雅地处理吗?
我看到AMPv2处理长消息,但我认为Twisted实现是针对AMPv1的。
我怀疑分块将成为答案的一部分,但我不确定如何做到这一点。我只有一种容易受到这些长消息影响的方法,因此我不需要最通用的解决方案。如果有帮助,我愿意制作一个不同的amp.Argument
子类。
最佳答案
您可以使用以下代码
# From lp:~glyph/+junk/amphacks
"""
An argument type for sending medium-sized strings (more than 64k, but small
enough that they still fit into memory and don't require streaming).
"""
from cStringIO import StringIO
from itertools import count
from twisted.protocols.amp import AMP, Argument, Command
CHUNK_MAX = 0xffff
class BigString(Argument):
def fromBox(self, name, strings, objects, proto):
value = StringIO()
value.write(strings.get(name))
for counter in count(2):
chunk = strings.get("%s.%d" % (name, counter))
if chunk is None:
break
value.write(chunk)
objects[name] = value.getvalue()
def toBox(self, name, strings, objects, proto):
value = StringIO(objects[name])
firstChunk = value.read(CHUNK_MAX)
strings[name] = firstChunk
counter = 2
while True:
nextChunk = value.read(CHUNK_MAX)
if not nextChunk:
break
strings["%s.%d" % (name, counter)] = nextChunk
counter += 1
class Send(Command):
arguments = [('big', BigString())]
class Example(AMP):
@Send.responder
def gotBig(self, big):
print 'Got a big input', len(big)
f = file("OUTPUT", "wb")
f.write(big)
f.close()
return {}
def main(argv):
from twisted.internet import reactor
from twisted.internet.protocol import Factory, ClientCreator
if argv[1] == 'client':
filename = argv[2]
def connected(result):
result.callRemote(Send, big=file(filename).read())
ClientCreator(reactor, AMP).connectTCP("localhost", 4321).addCallback(
connected)
reactor.run()
elif argv[1] == 'server':
f = Factory()
f.protocol = Example
reactor.listenTCP(4321, f)
reactor.run()
else:
print "Specify 'client' or 'server'."
if __name__ == '__main__':
from sys import argv as arguments
main(arguments)
PS:该代码取自https://raw.githubusercontent.com/fusionapp/documint/8fdbaeb3aeb298afff4ba951243d03c98fe8ff99/documint/mediumbox.py
关于python - 扭曲AMP-如何发送大于64K的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57078561/