我想在我的Voltron应用程序中使用RPC调用,但我无法使任何调用工作。所有调用都失败,并出现“no route to host”错误
<stderr> ERROR: Unreachable: VIP error (113): No route to host: rpcserver.agent_1
实际上有两个代理,一个是导出RPC过程的“服务器”代理,另一个是调用该过程的“客户机”代理。在
在“服务器”代理中,我导出了代理类的方法,如下所示:
^{pr2}$“客户端”代理按如下方式调用导出的方法:
self.vip.rpc.call(sender, 'setConfig', self.config[sender]).get()
其中“sender”是“server”代理的VIP标识(原来是“rpcserver.agent_1,对应于从接收pubsub消息时“sender”参数的值rpcserver.agent. 我把身份定义为rpcserver.agent_{n} 在标识文件中)。在
我的问题是:
1我是不是做了一些明显的错误或者遗漏了正确设置RPC子系统的步骤?
2self.vip.rpc.call(peer, method, ...)
中的“peer”参数是否应为代理的标识?这在文档中并不清楚(我尝试过其他选项,如代理名称或uuid,但都不起作用)
我在Ubuntu虚拟机上运行voltron5.1.0。在
如果有任何帮助,我们将不胜感激。 谨致问候
详细信息:
这是用于互连多个设备的控制应用程序。代理根据网络中可用的设备动态加载。我想试试RPCs,而不是只使用pubsub。我已经非常彻底地搜索了voltron代码和文档,以获得rpcapi的详细信息,但到目前为止没有任何结果。在
最小“服务器”类:
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/clientrady”的pubsub消息。在
实际行为:RPc调用失败,错误为“无法访问:VIP错误(113):没有到主机的路由:rpcclient.agent_1““
编辑 我最终发现问题是,伏尔特龙内部的特工身份以一个'\n'字符结尾。这是由于gedit自动附加它,显然字符串没有被voltron剥离。在
关于如何创建一个RPC方法,我认为您已经正确地做了一些事情(尽管:
可能是:
^{pr2}$因为您没有更改方法名)。在
就进行RPC调用而言,第一个参数实际上是代理标识或地址。在
如果您想查看更多示例,请查看services/core/MasterDriverAgent/master_driver/interfaces中的Modbus或Bacnet驱动程序。在
其他注意事项:
配置存储可用于设置代理配置。这方面的例子可以在voltron/platform/agent/base中找到_天气.py(以及许多其他代理商)
虽然我不是很熟悉,但似乎您要做的事情可以通过利用主驱动程序的特性来完成。我相信市场服务代理可能会与您试图实现的设计功能共享,可以在services/core/MarketServiceAgent找到它。
相关问题 更多 >
编程相关推荐