Subsequent Call to Actor Freezes Program
I put together the code below; the intent was to have a non-blocking server accept a connection and then pass off this connection to an actor for further processing. This works the first time through, but on the subsequent request the program freezes at conServ ! servSoc.accept
. Any ideas why this is happening?
import java.net._
import java.io._
import java.nio._
import java.nio.channels._
import java.util._
import scala.actors.Actor
import scala.actors.Actor._
def test() = {
var channel: ServerSocketChannel = null
val isa: InetSocketAddress = new InetSocketAddress(23)
val conServ = actor {
react {
case conn: Socket => {
try {
var pw: PrintWriter = new PrintWriter(conn.getOutputStream(), true)
pw.println("Current time: " + new Date)
pw.close
conn.close
} catch {
case ioe: IOException => println("IOException: " + ioe.getMessage)
case e: Exception => println("Exception: " + e.getMessage)
}
}
}
}
try {
channel = ServerSocketChannel.open
channel.configureBlocking(false)
channel.socket().bind(isa)
var selector: Selector = Selector.open
channel.register(selector, SelectionKey.OP_ACCEPT)
println("** Server ready for requests **")
while (true) {
if (selector.select > 0) {
var selKeys: Set[SelectionKey] = selector.selectedKeys
var selIt: Iterator[SelectionKey] = selKeys.iterator
while (selIt.hasNext) {
var key: SelectionKey = selIt.next.asInstanceOf[SelectionKey]
selIt.remove
if (key.isAcceptable) {
var ssc: ServerSocketChannel = key.channel.asInstanceOf[ServerSocketChannel]
var servSoc: ServerSocket = ssc.socket
try {
conServ ! servSoc.accept
} catch {
case ioe: IOException => println(ioe.printStackTrace)
}
}
}
} else {
continue
}
}
} catch {
case ioe开发者_StackOverflow中文版: IOException => println("Could not listen to port 23. " + ioe.printStackTrace)
case e: Exception => println("Error: " + e.printStackTrace)
}
}
test
Enclose your react
in a loop
block like this:
val conServ = actor {
loop {
react {
// ...
}
}
}
What happens now, is that your actor is started, processes the first message and is not "reacting" again to process additional message from its queue.
See An actor's act method that uses loop.
This is what an actor do, treating one message at the time. What you want is a separate thread to handle each request. For this you can try using Futures.
精彩评论