我使用以下方法对喷雾 jar 进行了非常基本的测试:
这是我的代码:
val myListener: ActorRef = system.actorOf(Props[TestHttpListener], "httpListener")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
httpListener
对 Http.Connected
使用react与 Http.Register(self)
.我使用 sbt 来运行我的代码。它失败并返回
AbstractMethodError
:[ERROR] [07/12/2014 18:46:48.364] [default-akka.actor.default-dispatcher-5] [ActorSystem(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-5] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled
java.lang.AbstractMethodError: spray.can.HttpManager.akka$actor$ActorLogging$_setter_$log_$eq(Lakka/event/LoggingAdapter;)V
at akka.actor.ActorLogging$class.$init$(Actor.scala:335)
at spray.can.HttpManager.<init>(HttpManager.scala:29)
at spray.can.HttpExt$$anonfun$1.apply(Http.scala:153)
at spray.can.HttpExt$$anonfun$1.apply(Http.scala:153)
at akka.actor.TypedCreatorFunctionConsumer.produce(Props.scala:422)
at akka.actor.Props.newActor(Props.scala:331)
at akka.actor.ActorCell.newActor(ActorCell.scala:534)
at akka.actor.ActorCell.create(ActorCell.scala:560)
at akka.actor.dungeon.FaultHandling$class.finishCreate(FaultHandling.scala:135)
at akka.actor.dungeon.FaultHandling$class.faultCreate(FaultHandling.scala:129)
at akka.actor.ActorCell.faultCreate(ActorCell.scala:338)
at akka.actor.dungeon.FaultHandling$class.faultRecreate(FaultHandling.scala:58)
at akka.actor.ActorCell.faultRecreate(ActorCell.scala:338)
at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:428)
at akka.actor.ActorCell.systemInvoke(ActorCell.scala:447)
at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:262)
at akka.dispatch.Mailbox.run(Mailbox.scala:218)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:385)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
最佳答案
在 Scala 世界中,小心版本非常重要,因为一切都在迅速发展,并且无法保证主要版本之间的向后兼容性。
喷雾取决于 Akka 和 this page包含有关支持的组合的信息。
spray 1.3.1 is built against Scala 2.10.3 and Akka 2.3.0 as well as Scala 2.11.1 and Akka 2.3.2.
因此,如果您使用 Scala 2.10.3,则 Akka 的正确版本至少应为 2.3.0。
此外,我认为您正在遵循的示例来自 this页面不是很好。
首先,它忽略了使用
IO(Http) ! Http.Bind(...)
初始化事物的代码这一事实。必须在 Actor 里面。 Actor ,收到Http.Bind
尝试回复 Http.Bound
而且由于来电者不是 Actor ,因此您会收到死信。所以,我建议做这样的事情:
class MyApp extends Actor {
implicit val system = context.system
override def receive: Receive = {
case "start" =>
val myListener: ActorRef = system.actorOf(Props[TestHttpListener], "httpListener")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
}
}
然后从
main()
您需要执行的应用程序方法:val myApp: ActorRef = system.actorOf(Props[MyApp], "myApp")
myApp ! "start"
从示例中不太容易理解的另一件事是,在您的监听器 actor 中,您不仅需要处理消息,还需要在每个连接上注册自己:
class TestHttpListener extends Actor {
def receive = {
case HttpRequest(HttpMethods.GET, Uri.Path("/ping"), _, _, _) =>
sender() ! HttpResponse(entity = "PONG")
case c : Tcp.Connected =>
sender() ! Http.Register(self)
}
}
关于scala - 使用 scala akka spray can 对 http 服务器进行非常基本的测试时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24714631/