OXM*_*456 10 scala jline actor
首先,我正在学习scala和java世界的新手.我想创建一个控制台并将此控制台作为可以启动和停止的服务运行.我能够将ConsoleReader运行到Actor中,但我不知道如何正确地停止ConsoleReader.这是代码:
import eu.badmood.util.trace
import scala.actors.Actor._
import tools.jline.console.ConsoleReader
object Main {
def main(args:Array[String]){
//start the console
Console.start(message => {
//handle console inputs
message match {
case "exit" => Console.stop()
case _ => trace(message)
}
})
//try to stop the console after a time delay
Thread.sleep(2000)
Console.stop()
}
}
object Console {
private val consoleReader = new ConsoleReader()
private var running = false
def start(handler:(String)=>Unit){
running = true
actor{
while (running){
handler(consoleReader.readLine("\33[32m> \33[0m"))
}
}
}
def stop(){
//how to cancel an active call to ConsoleReader.readLine ?
running = false
}
}
Run Code Online (Sandbox Code Playgroud)
我也在寻找有关此代码的任何建议!
从输入读取字符的底层调用是阻塞的。在非 Windows 平台上,它将System.in.read()使用org.fusesource.jansi.internal.WindowsSupport.readByte.
因此,您面临的挑战是当您想要停止控制台服务时导致阻塞调用返回。请参阅http://www.javaspecialists.eu/archive/Issue153.html和是否可以从具有超时的InputStream 中读取?一些想法...一旦你弄清楚了,当你的控制台服务停止时read返回-1,这样就ConsoleReader认为它已经完成了。您需要ConsoleReader使用该调用的您的版本:
tools.jline.AnsiWindowsTerminal并使用ConsoleReader带有 a 的构造函数Terminal(否则AnsiWindowsTerminal将直接使用 WindowsSupport.readByte`)ConsoleReader构造函数需要一个InputStream,你可以提供你自己的包装器System.in 还有一些想法:
scala.Console对象,因此为了减少混乱,请以不同的方式命名您的对象。System.in是一种独特的资源,因此您可能需要确保Console.readLine一次只有一个调用者使用。现在start将直接呼叫readLine,并且多个呼叫者可以呼叫start。也许控制台服务可以readLine维护一个处理程序列表。