随后调用演员冻结计划

时间:2011-05-07 04:25:10

标签: sockets scala actor

我把下面的代码放在一起;目的是让 -blocking服务器接受连接,然后将此连接传递给actor以进行进一步处理。这是第一次通过,但在随后的请求中,程序冻结在conServ ! servSoc.accept。任何想法为什么会发生这种情况?

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: IOException => println("Could not listen to port 23. " + ioe.printStackTrace)
        case e: Exception => println("Error: " + e.printStackTrace)
    }
}

test

2 个答案:

答案 0 :(得分:3)

react封闭在loop块中,如下所示:

val conServ = actor { 
  loop {
    react {
      // ...
    }
  }
}

现在发生的事情是,您的actor已启动,处理第一条消息,并且不再“响应”以处理其队列中的其他消息。

An actor's act method that uses loop

答案 1 :(得分:2)

这是演员所做的事情,当时处理一条消息。你想要的是一个单独的线程来处理每个请求。为此,您可以尝试使用期货。