spray-can simple-http-server 示例 如何处理绑定消息?
spray-can simple-http-server example how are Bound messages handled?
在 spray-can HTTP 服务器示例中,当我 运行 服务器时,我没有在日志中看到任何 "Bound" 消息:
https://github.com/spray/spray/tree/master/examples/spray-can/simple-http-server/src/main
但是,如果我尝试创建自己的服务器并忽略 Bound
消息,我会让他们进入死信:
$ sbt run
[info] Set current project to pingpong (in build file:/D:/Projects/pingpong/)
[info] Updating {file:/D:/Projects/pingpong/}pingpong...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Running drozdyuk.pingpong.Main
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8081
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/deadLetters] Message [akka.io.Tcp$Bound] from Actor[akka://default/us
er/IO-HTTP/listener-0#-892116855] to Actor[akka://default/deadLetters] was not d
elivered. [1] dead letters encountered. This logging can be turned off or adjust
ed with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letter
s-during-shutdown'.
我的问题主要是出于好奇,示例中如何处理 Bound
消息?是某种日志吞噬了它们还是其他什么?
我的代码 Main.scala
:
package drozdyuk.pingpong
import akka.actor.{ActorSystem, Props}
import akka.io.IO
import spray.can.Http
object Main extends App {
implicit val system = ActorSystem()
// the handler actor replies to incoming HttpRequests
val handler = system.actorOf(Props[WebService], name = "handler")
val PORT = 8081
val DOMAIN = "localhost"
IO(Http) ! Http.Bind(handler, interface = DOMAIN, port = PORT)
}
和我的 WebService.scala
:
package drozdyuk.pingpong
import akka.actor._
import spray.http.HttpMethods.{GET}
import spray.can.Http
import spray.http.{HttpRequest, HttpResponse, Uri}
class WebService extends Actor with ActorLogging {
def receive = {
// New connection - register self as handler
case _: Http.Connected => sender ! Http.Register(self)
case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
sender ! HttpResponse(entity = "pong")
case HttpRequest(GET, Uri.Path("/pong"), _, _, _) =>
sender ! HttpResponse(entity = "ping")
case _: HttpRequest => sender ! HttpResponse(status = 404, entity = "Unknown resource!")
}
}
您可以在 Main
中使用另一个版本的 tell
:
IO(Http).tell(Http.Bind(handler, interface = DOMAIN, port = PORT), sender = handler)
然后在您的 WebService 中处理 Bound
消息:
class WebService extends Actor with ActorLogging {
def receive = {
case Http.Bound(address) =>
//all other cases...
}
}
在您的情况下,您使用的是
def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit
并且 Main
范围内没有隐式发件人,因此将使用默认值 noSender
。
我试过了,对我来说效果很好:
import akka.actor._
import akka.io._
import spray.can.Http
import spray.http.HttpResponse
import spray.http.HttpRequest
import spray.http.Uri
import spray.http.HttpMethods.{GET}
class WebService extends Actor with ActorLogging {
def receive = {
case _: Http.Connected => sender ! Http.Register(self)
case _: HttpRequest => sender ! HttpResponse(status = 404, entity = "Unknown resource!")
case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
sender ! HttpResponse(entity = "pong")
//all other cases...
}
}
object TestSpray extends App {
implicit val system = ActorSystem()
val myListener: ActorRef = system.actorOf(Props[WebService], name = "handler")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
}
在 spray-can HTTP 服务器示例中,当我 运行 服务器时,我没有在日志中看到任何 "Bound" 消息:
https://github.com/spray/spray/tree/master/examples/spray-can/simple-http-server/src/main
但是,如果我尝试创建自己的服务器并忽略 Bound
消息,我会让他们进入死信:
$ sbt run
[info] Set current project to pingpong (in build file:/D:/Projects/pingpong/)
[info] Updating {file:/D:/Projects/pingpong/}pingpong...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Running drozdyuk.pingpong.Main
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8081
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/deadLetters] Message [akka.io.Tcp$Bound] from Actor[akka://default/us
er/IO-HTTP/listener-0#-892116855] to Actor[akka://default/deadLetters] was not d
elivered. [1] dead letters encountered. This logging can be turned off or adjust
ed with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letter
s-during-shutdown'.
我的问题主要是出于好奇,示例中如何处理 Bound
消息?是某种日志吞噬了它们还是其他什么?
我的代码 Main.scala
:
package drozdyuk.pingpong
import akka.actor.{ActorSystem, Props}
import akka.io.IO
import spray.can.Http
object Main extends App {
implicit val system = ActorSystem()
// the handler actor replies to incoming HttpRequests
val handler = system.actorOf(Props[WebService], name = "handler")
val PORT = 8081
val DOMAIN = "localhost"
IO(Http) ! Http.Bind(handler, interface = DOMAIN, port = PORT)
}
和我的 WebService.scala
:
package drozdyuk.pingpong
import akka.actor._
import spray.http.HttpMethods.{GET}
import spray.can.Http
import spray.http.{HttpRequest, HttpResponse, Uri}
class WebService extends Actor with ActorLogging {
def receive = {
// New connection - register self as handler
case _: Http.Connected => sender ! Http.Register(self)
case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
sender ! HttpResponse(entity = "pong")
case HttpRequest(GET, Uri.Path("/pong"), _, _, _) =>
sender ! HttpResponse(entity = "ping")
case _: HttpRequest => sender ! HttpResponse(status = 404, entity = "Unknown resource!")
}
}
您可以在 Main
中使用另一个版本的 tell
:
IO(Http).tell(Http.Bind(handler, interface = DOMAIN, port = PORT), sender = handler)
然后在您的 WebService 中处理 Bound
消息:
class WebService extends Actor with ActorLogging {
def receive = {
case Http.Bound(address) =>
//all other cases...
}
}
在您的情况下,您使用的是
def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit
并且 Main
范围内没有隐式发件人,因此将使用默认值 noSender
。
我试过了,对我来说效果很好:
import akka.actor._
import akka.io._
import spray.can.Http
import spray.http.HttpResponse
import spray.http.HttpRequest
import spray.http.Uri
import spray.http.HttpMethods.{GET}
class WebService extends Actor with ActorLogging {
def receive = {
case _: Http.Connected => sender ! Http.Register(self)
case _: HttpRequest => sender ! HttpResponse(status = 404, entity = "Unknown resource!")
case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
sender ! HttpResponse(entity = "pong")
//all other cases...
}
}
object TestSpray extends App {
implicit val system = ActorSystem()
val myListener: ActorRef = system.actorOf(Props[WebService], name = "handler")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
}