如何使用 snmp4j 在 SCALA 中获取异步 SNMPv2
How to get Asynchronous SNMPv2 in SCALA with snmp4j
我正在查询 SNMP,我想在数据检索完成时执行回调。为此,我使用以下代码:
def treeWalk(rootOid: String)(callback: (Seq[Tuple2[OID, Variable]]) => Unit) {//{{{
val transport = new DefaultUdpTransportMapping
val snmp = new Snmp(transport)
transport.listen
val target = new CommunityTarget
target.setCommunity(new OctetString(community))
target.setAddress(GenericAddress.parse("udp:" + address + "/161"))
target.setRetries(retries)
target.setTimeout(timeout)
target.setVersion(SnmpConstants.version2c)
val treeUtil = new TreeUtils(snmp, new DefaultPDUFactory)
var variables: Seq[VariableBinding] = List()
var _isFinished = false
val listener = new TreeListener {
def next(event: TreeEvent) = {
println("NEXT")
val vars = event.getVariableBindings
if(vars != null)
variables ++= vars
true
}
def isFinished() = _isFinished
def finished(event: TreeEvent) {
val vars = event.getVariableBindings
println("DONE")
if(vars != null)
variables ++= vars
_isFinished = true
snmp.close
callback(variables.map(v => (v.getOid, v.getVariable)))
}
}
treeUtil.walk(target, Array(new OID(rootOid)), null, listener)
}
我没有收到任何错误或异常,但是我从未在 next() 和 finished() 中看到打印行,而且回调也没有执行。我做错了什么,我应该如何将事件侦听器挂接到它?
PS: 一行同步版本returns数据就好了...
我正在使用 Scala 2.11.6 和 SNMP4J 2.3
处理回调时,您必须考虑到主线程很容易在您的异步调用之前完成,从而导致主线程(以及程序的其余部分)在异步任务完成之前终止并且回调到达。执行此操作的简单方法是调用 Thread.sleep()
并让您的主线程暂停一段特定的等待时间。但是,您可以对此进行改进。一种选择是使用这样的代码片段:
var callbackComplete = false
someAsyncMethodWithCallback(callback)
while (!callbackComplete){
Thread.sleep(100)
}
然后您需要做的就是让您的回调包含一行内容 callbackComplete = true
,这将使它终止。
但是,这远非理想(但如果您只需要快速临时修复,那很好)。理想情况下,您应该通读 Scala 文档中的 Futures and Promises 页面。它详细说明了如何正确处理 Futures 以及处理失败,并且应该被视为处理异步调用的正确资源。
我正在查询 SNMP,我想在数据检索完成时执行回调。为此,我使用以下代码:
def treeWalk(rootOid: String)(callback: (Seq[Tuple2[OID, Variable]]) => Unit) {//{{{
val transport = new DefaultUdpTransportMapping
val snmp = new Snmp(transport)
transport.listen
val target = new CommunityTarget
target.setCommunity(new OctetString(community))
target.setAddress(GenericAddress.parse("udp:" + address + "/161"))
target.setRetries(retries)
target.setTimeout(timeout)
target.setVersion(SnmpConstants.version2c)
val treeUtil = new TreeUtils(snmp, new DefaultPDUFactory)
var variables: Seq[VariableBinding] = List()
var _isFinished = false
val listener = new TreeListener {
def next(event: TreeEvent) = {
println("NEXT")
val vars = event.getVariableBindings
if(vars != null)
variables ++= vars
true
}
def isFinished() = _isFinished
def finished(event: TreeEvent) {
val vars = event.getVariableBindings
println("DONE")
if(vars != null)
variables ++= vars
_isFinished = true
snmp.close
callback(variables.map(v => (v.getOid, v.getVariable)))
}
}
treeUtil.walk(target, Array(new OID(rootOid)), null, listener)
}
我没有收到任何错误或异常,但是我从未在 next() 和 finished() 中看到打印行,而且回调也没有执行。我做错了什么,我应该如何将事件侦听器挂接到它?
PS: 一行同步版本returns数据就好了...
我正在使用 Scala 2.11.6 和 SNMP4J 2.3
处理回调时,您必须考虑到主线程很容易在您的异步调用之前完成,从而导致主线程(以及程序的其余部分)在异步任务完成之前终止并且回调到达。执行此操作的简单方法是调用 Thread.sleep()
并让您的主线程暂停一段特定的等待时间。但是,您可以对此进行改进。一种选择是使用这样的代码片段:
var callbackComplete = false
someAsyncMethodWithCallback(callback)
while (!callbackComplete){
Thread.sleep(100)
}
然后您需要做的就是让您的回调包含一行内容 callbackComplete = true
,这将使它终止。
但是,这远非理想(但如果您只需要快速临时修复,那很好)。理想情况下,您应该通读 Scala 文档中的 Futures and Promises 页面。它详细说明了如何正确处理 Futures 以及处理失败,并且应该被视为处理异步调用的正确资源。