UnetAgent路由算法实现遇错:startnode代理加载失败求助
路由算法实现编译错误排查
我正在实现一种路由算法,核心逻辑:
- 节点A向不存在的节点发送
RouteDiscoveryReq,触发邻居发现 - 邻居节点a1、a2收到
RouteDiscoveryNtf后,等待随机时长(避免冲突)再向节点A回复随机数
给a1、a2部署startnode.groovy代理时,加载报错:
BUG! exception in phase 'semantic analysis' ...The lookup for startnode caused a failed compilation
相关代码片段
1. multiHop.groovy(仿真脚本)
部署6个节点,其中a1、a2为节点A的邻居并运行startnode代理,以下是关键代码:
def n2 = node 'A', address: 2, location: [ 0.km, 2.km, 0.m], web: 8087, stack: "$home/etc/setup" n2.startup={ def rdp = agentForService Services.ROUTE_MAINTENANCE subscribe topic(rdp); def datagram = agentForService(org.arl.unet.Services.DATAGRAM) subscribe topic(datagram); n = [] rdp << new RouteDiscoveryReq(to: 100, count: 1) while (ntf = receive(RouteDiscoveryNtf, 10000)) { n << ntf.nextHop // 添加邻居到列表 } n = n.unique() // 去重 println("Neighbors are ${n}") } def a1 = node 'a1', address: 3, location: [ 0.km, 3.km, -1850.m], web: 8088, stack: "$home/etc/setup" a1.startup={ container.add 'sn', new startnode(); } def a2 = node 'a2', address: 4, location: [ 1.5.km, 3.km, -1850.m], web: 8089, stack: "$home/etc/setup" a2.startup={ container.add 'sn', new startnode(); }
2. startnode.groovy(代理脚本)
实现等待随机时长后回复随机数的逻辑:
import org.arl.fjage.* import org.arl.fjage.param.Parameter // import static org.arl.unet.utils.MathUtils.* import org.arl.unet.* class startnode extends UnetAgent { int delay = Math.abs(new Random().nextInt()) % 1000 + 1 int rand_num = Math.abs(new Random().nextInt()) % 10 + 1 void startup() { subscribeForServices(Services.DATAGRAM) subscribeForServices(Services.ROUTE_MAINTENANCE) } void processMessage(Message msg) { if (msg instanceof RouteDiscoveryNtf) { add new WakerBehavior(delay, { send new DatagramReq( recipient: msg.sender, to: msg.from, data: rand_num ) }) } } }
错误原因及修复方案
- 类名不符合Groovy规范:Groovy要求类名采用大驼峰命名,将
startnode改为StartNode,同时在multiHop.groovy中实例化时改为new StartNode() - 缺少Random类导入:
startnode.groovy中使用了Random但未导入,需添加import java.util.Random - 变量作用域问题:节点A的启动脚本中
n未声明,改为def n = []避免作用域混淆 - 订阅服务简化:可以直接用
subscribe Services.ROUTE_MAINTENANCE替代通过代理订阅topic的写法
修复后的StartNode.groovy:
import org.arl.fjage.* import org.arl.fjage.param.Parameter import org.arl.unet.* import java.util.Random class StartNode extends UnetAgent { int delay = Math.abs(new Random().nextInt()) % 1000 + 1 int rand_num = Math.abs(new Random().nextInt()) % 10 + 1 void startup() { subscribe Services.DATAGRAM subscribe Services.ROUTE_MAINTENANCE } void processMessage(Message msg) { if (msg instanceof RouteDiscoveryNtf) { add new WakerBehavior(delay, { send new DatagramReq( recipient: msg.sender, to: msg.from, data: rand_num ) }) } } }
修复后的multiHop.groovy中a1、a2启动代码:
def a1 = node 'a1', address: 3, location: [ 0.km, 3.km, -1850.m], web: 8088, stack: "$home/etc/setup" a1.startup={ container.add 'sn', new StartNode(); } def a2 = node 'a2', address: 4, location: [ 1.5.km, 3.km, -1850.m], web: 8089, stack: "$home/etc/setup" a2.startup={ container.add 'sn', new StartNode(); }
内容的提问来源于stack exchange,提问作者Radhika Suradkar
相关产品推荐
相关产品推荐

