我正在编写一个基于文本的老式telnet服务器,现在它是Scala中一个美化的聊天室,带有基于Akkaactor的IO。正在发生的事情是客户端客户端将开始键入某些内容,然后会发生一个事件,当它被写入时,它会清除任何已经键入的内容。 在下面的示例中,Tom 开始键入"say are you?",但 Fred 在只键入"say How ar"并且此输入被清除后到达:
Tom > say How ar
Fred has arrived.
Tom >
有没有办法让telnet重新显示它尚未刷新的输出缓冲区?
这是服务器:
class TcpServer(port: Int) extends Actor {
import TcpServer._
import context.system
val log = Logging(system, this)
var connectionNum: Int = 1
log.info(STARTING_SERVER)
IO(Tcp) ! Bind(self, new InetSocketAddress("0.0.0.0", port))
def receive = {
case b @ Bound(localAddress) =>
log.info(PORT_BOUND, localAddress)
case c @ Connected(remote, local) =>
log.info(CONNECTION_ACCEPTED)
context.actorOf(ConnectionHandler.connectionProps(sender()), s"conn$connectionNum")
connectionNum += 1
case CommandFailed(_: Bind) =>
log.error(BINDING_FAILED)
context stop self
}
}
下面是 ConnectionHandler,它是配套对象,以及它使用的消息案例类:
class ConnectionHandler(connection: ActorRef) extends Actor {
import context._
val log = Logging(context.system, this)
connection ! Register(self)
var delegate = actorOf(Props[LoginHandler], "login")
watch(delegate)
def receive = {
case Received(data) =>
val dataString = data.utf8String.trim
log.info("Received data from connection: {}", dataString)
delegate ! Input(dataString)
case Output(content) =>
connection ! Write(ByteString(content))
case LoggedIn(user) =>
unwatch(delegate)
delegate ! PoisonPill
delegate = actorOf(UserHandler.connectionProps(user), user.name.toLowerCase)
watch(delegate)
case Terminated =>
log.warning("User delegate died unexpectedly.")
connection ! ConfirmedClose
case CloseConnection(message) =>
connection ! Write(ByteString(message + "n"))
connection ! ConfirmedClose
log.info("User quit.")
case ConfirmedClosed =>
log.info("Connection closed.")
stop(self)
case PeerClosed =>
log.info("Connection closed by client.")
stop(self)
}
}
object ConnectionHandler {
def connectionProps(connection: ActorRef): Props = Props(new ConnectionHandler(connection))
}
case class Input(input: String)
case class Output(output: String)
case class LoggedIn(user: User)
case class CloseConnection(message: String)
好的,在最终正确措辞我的谷歌查询之后,我在这里找到了我需要的东西:强制远程登录客户端进入字符模式
基本的解决方案是,我强制客户端在时间模式下进入角色,并回显我关心的角色。 这样做的好处是,现在我可以执行选项卡完成,命令历史记录并使密码不显示。
以下是相关的代码片段:
val controlString = ByteString('u00ff','u00fb','u0001','u00ff','u00fb','u0003','u00ff','u00fc','u0022')
connection ! Write(controlString)