开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜