Последующая программа «Звонок актеру» - PullRequest
1 голос
/ 07 мая 2011

Я собрал код ниже;Намерение состояло в том, чтобы не -блокирующий сервер принял соединение и затем передал это соединение субъекту для дальнейшей обработки.Это работает в первый раз, но при последующем запросе программа зависает на 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 ]

3 голосов
/ 07 мая 2011

Заключите ваш react в loop блок следующим образом:

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

Что происходит сейчас, так это то, что ваш актер запущен, обрабатывает первое сообщение и больше не «реагирует» на обработку дополнительного сообщения из своей очереди.

См. Метод актерского акта, использующий цикл .

2 голосов
/ 07 мая 2011

Это то, что делает актер, обрабатывая одно сообщение за раз.То, что вы хотите, это отдельный поток для обработки каждого запроса.Для этого вы можете попробовать использовать Futures.

...