基于Scala Actor的Web服务器

时间:2014-10-14 04:31:43

标签: scala akka

我试图在Scala中实现一个非常基本的Web服务器,基于Akka Actors。

我遇到的问题是我在浏览器上发出的第一个请求完全正常,但其余的都是零星的,有时加载浏览器页面的响应再次很好,有时根本没有做任何事情。我想知道我是不是错误地关闭了某些东西,或者只是创造了大量永不停止的自由漫游演员。

相关代码:

def startHttpServer(port: Int) = {
  try {
    val system = ActorSystem("BasicServerSystem")
    val requestActor = system.actorOf(Props[HttpRequestActor], name = "requestActor")
    val server = new ServerSocket(port)
    logger.info(s"BasicServer listening on port $port")
    while (true) {
      val socket = server.accept()
      requestActor ! socket
    }
  } catch {
    case e: Exception => logger.error(e.getMessage)
  }
}

class HttpRequestActor extends Actor {
  final val logger = Logger.createLogger(classOf[HttpRequestActor])

  override def receive: Receive = {
    case sock: Socket =>
      try {
        val requestId = java.util.UUID.randomUUID.toString
        val responseActor = context.actorOf(Props[HttpResponseActor], name = s"responseActor$requestId")
        responseActor ! sock
      } catch {
        case e: Exception => logger.error(e.getMessage)
      }
  }
}

class HttpResponseActor extends Actor {
  final val logger = Logger.createLogger(classOf[HttpResponseActor])

  override def receive: Actor.Receive = {
    case sock: Socket =>
      try {
        val out = new PrintStream(sock.getOutputStream)
        val date = new Date()
        out.println("Received on " + date)
        out.close()
      } catch {
        case e: Exception => logger.error(e.getMessage)
      } finally {
        sock.close()
      }
  }
}

另外值得注意的是,我不知道在哪里关闭套接字。我在这里走在正确的轨道上,或者这对演员来说是一个可怕的用例吗?

1 个答案:

答案 0 :(得分:0)

您正在响应新的TCP会话,而不是新的HTTP请求。由于浏览器会缓存TCP会话,因此每次发送新请求时都可能无法收到新的套接字连接。当您启动一个新的浏览器实例时,您肯定会得到一个新的套接字连接,您可以响应(正如您所注意到的)。刷新现有浏览器时,是否打开新的TCP会话取决于浏览器中的超时。