我使用Kademlia库来创建P2P网络。一旦节点加入网络,我希望用户能够在命令行中询问获取密钥或在网络中放置元组。
我的问题是I / O正在阻止连接,这意味着在输入用户输入时节点将与网络断开连接。
我的代码如下:
from kademlia.network import Server
from twisted.internet import reactor, stdio
from twisted.python import log
from twisted.internet.task import LoopingCall
import sys
log.startLogging(sys.stdout)
def usi(server):
key = str(raw_input())
value = str(raw_input())
print("Putting data: (" + key + ";" + value + ")")
server.set(key, value).addCallback(done)
def done(res):
print "Key put:"
print res
def boostrapDone(found, server, key):
if len(found) == 0:
print 'could not bootstrap'
reactor.stop()
server.set(key, 'value').addCallback(done)
srv = Server()
srv.saveStateRegularly('out.pik')
srv.listen(8887)
srv.bootstrap([('127.0.0.1', 8888)]).addCallback(boostrapDone, srv, 'test')
loop = LoopingCall(usi, srv)
loop.start(2)
reactor.run()
我已经阅读了几个有关此问题的SO问题,我已经从twisted example读取了stdin.py和stdio.py示例,似乎我需要在twisted协议上使用StandardIO。但是Kademlia使用高级类(Server)来简化协议的使用,我不知道是否可以在不修改库的情况下获得非阻塞I / O.
编辑:
我尝试以这种方式使用reactor.callInThread
:
def usi(server):
while True:
key = str(raw_input())
value = str(raw_input())
print("Putting data: (" + key + ";" + value + ")")
server.set(key, value).addCallback(done)
def done(res):
print "Key put:"
print res
def boostrapDone(found, server, key):
if len(found) == 0:
print 'could not bootstrap'
reactor.stop()
server.set(key, 'value').addCallback(done)
srv = Server()
srv.saveStateRegularly('out.pik')
srv.listen(8887)
srv.bootstrap([('127.0.0.1', 8888)]).addCallback(boostrapDone, srv, 'test')
reactor.callInThread(usi, srv)
reactor.run()
它似乎工作,但有时节点无法从其他节点获得响应,并将它从桶中删除,使他无法将元组放入网络,所以我猜我仍然做错了什么。 (我设法重现这个bug,它似乎发生在用户输入超过5秒时,kademlia无法从其他节点接收响应并超时)