我有一个使用akka的应用程序,现在我想通过套接字连接来连接它。因此,我使用类似于the one from the scala page的机制。
但是,如果我尝试tell
,当我打开OutputStream
时,目标不会收到任何消息。
这是我的源代码:
object Connector {
def main(args: Array[String]) {
val port = 1337
val conf = ConfigFactory.load
val system = ActorSystem("SDDB", conf.getConfig("SDDB"))
val master = system.actorOf(Props[TestActor])
master ! "a"
try {
val listener = new ServerSocket(port)
println("listening on port: " + port)
while (true)
new ConnectionThread(listener accept, master).start
listener close
} catch {
case e: IOException =>
System.err.println("Could not listen on port: " + port + ".")
System.exit(-1)
} finally {
system.shutdown
}
}
}
case class ConnectionThread(socket: Socket, master: ActorRef)
extends Thread("ConnectionThread") {
private val Select_* = """select (\w+) from (\w+) on (\d{4})-(\d\d)-(\d\d)""".r
private implicit var id = 0L
private implicit val timeout = Timeout(25.0 seconds)
master ! "b"
override def run {
master ! "c"
try{
master ! "d"
val in = new ObjectInputStream(socket getInputStream)
master ! "e"
val out = new ObjectOutputStream(socket getOutputStream)
out writeObject("listening")
out flush
master ! "f"
val command = in.readObject.asInstanceOf[String]
println("client sent: '" + command + "'")
// process the command
master ! "g"
out.writeObject("EOF")
out.flush
out.close
in.close
socket.close
} catch {
case e: SocketException =>
case e: IOException => e printStackTrace
}
}
}
class TestActor extends Actor with ActorLogging{
log info("TestActor running")
def receive = {
case s: String =>
log info("received: " + s)
}
}
我得到了输出:
listening on port: 1337
[INFO] TestActor running
[INFO] received: a
[INFO] received: b
[INFO] received: c
[INFO] received: d
现在我预计它会持续到g,但我会得到:
client sent: 'select content from testdata on 2012-07-06'
我发现它一直工作,直到我打开套接字的流,可能是因为tell
和ask
也是socketbased并使用套接字的输出流,胎面运行。然后套接字连接有效,但我无法将任何消息发送到actor-system。
我无法删除Connector和ConnectionThread。我该如何解决?
答案 0 :(得分:0)
我必须承认,我没有完全理解文档中的示例。但我发现使用ConnectionHelper
而不是直接寻址ActorRef
非常有效。
我将代码更改为以下内容:
object Connector {
def main(args: Array[String]) {
val port = 1337
val conf = ConfigFactory.load
val system = ActorSystem("SDDB", conf.getConfig("SDDB"))
// val master = system.actorOf(Props[TestActor], "master")
// master ! "a"
try {
val listener = new ServerSocket(port)
println("listening on port: " + port)
while (true)
// new ConnectionThread(listener accept, master.asInstanceOf[TestActor]).start
new ConnectionThread(listener accept, system).start
listener close
} catch {
case e: IOException =>
System.err.println("Could not listen on port: " + port + ".")
System.exit(-1)
} finally {
// master ! PoisonPill
system.shutdown
}
}
}
case class ConnectionThread(socket: Socket, sys: ActorSystem)
extends Thread("ConnectionThread") {
private val Select_* = """select (\w+) from (\w+) on (\d{4})-(\d\d)-(\d\d)""".r
private implicit var id = 0L
private implicit val timeout = Timeout(25.0 seconds)
private val conHelper = new ConnectionHelper
override def run {
try {
val out = new ObjectOutputStream(socket getOutputStream)
val in = new ObjectInputStream(socket getInputStream)
conHelper tell "funzt"
out writeObject ("Hi")
out.flush
val command = in.readObject.asInstanceOf[String]
println("received: " + command)
out writeObject ("test")
out.flush
out writeObject ("EOF")
out.flush
out.close
in.close
socket.close
}
}
private class ConnectionHelper {
val tester = sys.actorOf(Props[TestActor])
def tell(s: String) { tester ! s }
}
}
我真的不明白为什么会这样,而我的问题中的代码却没有。我欢迎所有的解释。