我想在我的 volttron 应用程序中使用 RPC 调用,但我无法让任何调用正常工作。所有调用都失败并出现“没有路由到主机”错误
<stderr> ERROR: Unreachable: VIP error (113): No route to host: rpcserver.agent_1
本质上,有两个代理,一个导出 RPC 过程的“服务器”代理,以及一个调用该过程的“客户端”代理。
在“服务器”代理中,我导出了代理类的方法,如下所示:
@RPC.export('setConfig')
def setConfig(self, config):
self.config = config
self.initialize_device()
“客户端”代理调用导出的方法如下:
self.vip.rpc.call(sender, 'setConfig', self.config[sender]).get()
其中“sender”是“server”代理的 VIP 身份(结果是“rpcserver.agent_1”并且对应于从 rpcserver.agent 接收 pubsub 消息时的“sender”参数的值。我已经定义了IDENTITY 文件中的 rpcserver.agent_{n} 身份)。
我的问题是: 1. 我是在做一些明显错误的事情还是错过了正确设置 RPC 子系统的某些步骤?2. “peer”参数是否self.vip.rpc.call(peer, method, ...)
预期是代理的身份?这在文档中并不清楚(我尝试了其他选项,例如代理名称或 uuid,但没有一个有效)
我在 Ubuntu VM 中运行 volttron 5.1.0。
对此的任何帮助将不胜感激。此致
细节:
这适用于互连多个设备的控制应用程序。代理根据网络中的可用设备动态加载。我想尝试 RPC 而不是只使用 pubsub。到目前为止,我已经彻底搜索了 Volttron 代码和文档以获取有关 RPC API 的详细信息,但无济于事。
最小的“服务器”类:
class rpcServerAgent(Agent):
def __init__(self, config, **kwargs):
super(rpcServerAgent, self).__init__(**kwargs)
self.config = config
@Core.receiver('onstart')
def onstart(self, sender, **kwargs):
self.vip.rpc.export(self.setConfig, name='setConfig') # Also tried online exporting
# Ask the client to call the exported procedure
myutils.publish(self, topic='rpc/test', message={}) # myutils.publish publishes the message on pubsub
@RPC.export('setConfig')
def setConfig(self, config):
self.config = config
self.initialize_device()
myutils.publish(self, topic='rpc/clientready')
def initialize_device(self):
pass
最小的“客户”类:
class rpcClientAgent(Agent):
def __init__(self, config, **kwargs):
super(rpcClientAgent, self).__init__(**kwargs)
self.config = {'rpcclient.agent_1': {'a': 0, 'b': 1}} # dummy config for rpcclient.agent
@Core.receiver('onstart')
def onstart(self, sender, **kwargs):
self.vip.pubsub.subscribe(peer='pubsub',
prefix='rpc',
callback=self.__handle_request__).get(timeout=5)
def call_RPC(self, sender):
sender = sender.strip() # volttron adds a newline at the end
self.vip.rpc.call(sender, 'setConfig', self.config[sender]).get() # assume that self.config[sender] is well-defined
@PubSub.subscribe('pubsub', 'rpc')
def __handle_request__(self, peer, sender, bus, topic, headers, message):
try:
msg = json.loads(message)
except:
raise ValueError("failed to decode message")
topics = topic.split('/')
if len(topics) > 1:
if topics[0] == 'rpc':
if topics[1] == 'test':
self.call_RPC(sender)
预期行为:调用导出的函数并发布主题为“rpc/clientready”的 pubsub 消息。
实际行为:RPc 调用失败并出现错误“无法访问:VIP 错误(113):没有到主机的路由:rpcclient.agent_1”
编辑 我最终发现问题在于 volttron 中的代理身份以“\n”字符结尾。这是由于 gedit 自动附加它,显然字符串没有被 volttron 剥离。