[英]python twisted json decoding
我已經使用python扭曲庫開發了以下代碼:
class Cache(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
def dataReceived(self, data):
request = json.loads(data)
self.factory.handle[request['command']](**request)
self.transport.write(data)
class CacheFactory(protocol.Factory):
def buildProtocol(self, addr):
return Cache(self)
def handle_get(self, **kwargs):
print 'get\n', kwargs
def handle_set(self, **kwargs):
print 'set\n', kwargs
def handle_delete(self, **kwargs):
print 'delete\n', kwargs
handle = {
'get': handle_get,
'set': handle_set,
'delete': handle_delete,
}
reactor.listenTCP(int(sys.argv[1]), CacheFactory())
reactor.run()
我使用telnet運行客戶端連接:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"command": "set", "value": 1234567890}
Connection closed by foreign host.
引發異常:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 84, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 69, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
return func(*args,**kw)
--- <exception caught here> ---
File "/usr/lib/python2.7/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
why = getattr(selectable, method)()
File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 460, in doRead
rval = self.protocol.dataReceived(data)
File "./server.py", line 18, in dataReceived
self.factory.handle[request['command']](**request)
exceptions.TypeError: handle_set() takes exactly 1 argument (0 given)
我不明白。 self.factory.handle[request['command']](**request)
行可能有問題,但我認為這是正確的-它隱式地傳遞了self
參數(畢竟是方法)並顯式地解壓縮了請求參數。 異常消息說該函數接受1個參數,這是一個謊言:),因為它接受2個參數: self, **kwargs
。 而且我傳遞了2個參數也不是正確的,因為我傳遞了2個參數。
有人可以幫助我發現問題嗎?
如果有幫助,則將json請求解碼為:
{u'command': u'set', u'value': 1234567890}
到目前為止, handle_*
方法是實例方法,而handle
字典指向未綁定的方法。 也就是說, self
不會被隱式傳遞。 嘗試以下方法:
class CacheFactory(protocol.Factory):
def buildProtocol(self, addr):
return Cache(self)
def handle_get(self, **kwargs):
print 'get\n', kwargs
def handle_set(self, **kwargs):
print 'set\n', kwargs
def handle_delete(self, **kwargs):
print 'delete\n', kwargs
def __init__(self, *args, **kwargs):
protocol.Factory.__init__(self, *args, **kwargs)
self.handle = {
'get': self.handle_get,
'set': self.handle_set,
'delete': self.handle_delete,
}
另外,您可以保持handle
不變並執行以下操作:
def dataReceived(self, data):
request = json.loads(data)
self.factory.handle[request['command']](self.factory, **request)
self.transport.write(data)
或者,你可以采取這種做法,那么你並不需要一個handle
字典兩種方式:
def dataReceived(self, data):
request = json.loads(data)
getattr(self.factory, "handle_%s" % (request['command'],))(**request)
self.transport.write(data)
還要注意,由於數據包可能會被任意拆分,因此dataReceived
(現在)是不安全的,也就是說,您可能不會一槍就收到整個json
消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.