1

我使用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 示例中的 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()

它似乎有效,但有时节点无法从其他节点获得响应,并将它们从他的存储桶中删除,使他无法将元组放入网络,所以我想我仍然做错了什么。(我设法重现了这个错误,它似乎发生在用户输入超过 5 秒时,kademlia 无法接收来自其他节点的响应并将它们超时)

4

0 回答 0