Joe*_*oel 4 scala httpserver akka spray
我做了一个非常基本的喷雾测试,使用:
这是我的代码:
val myListener: ActorRef = system.actorOf(Props[TestHttpListener], "httpListener")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
Run Code Online (Sandbox Code Playgroud)
该httpListener起反应对Http.Connected用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)
Run Code Online (Sandbox Code Playgroud)
在Scala世界中,小心版本是非常重要的,因为一切都在快速发展,并且不保证主要版本之间的向后兼容性.
喷雾取决于Akka,此页面包含有关支持的组合的信息.
spray 1.3.1针对Scala 2.10.3和Akka 2.3.0以及Scala 2.11.1和Akka 2.3.2构建.
因此,如果您使用Scala 2.10.3,正确版本的Akka将至少为2.3.0.
而且,我认为你从这个页面跟随的例子不是很好.
首先,它忽略了这样一个事实,即初始化事物的代码IO(Http) ! Http.Bind(...)必须在actor中.接受Http.Bind尝试回复的演员,Http.Bound因为来电者不是演员,你会收到死信.
所以,我建议做这样的事情:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后从main()您的应用程序的方法,您需要做:
val myApp: ActorRef = system.actorOf(Props[MyApp], "myApp")
myApp ! "start"
Run Code Online (Sandbox Code Playgroud)
另一个从示例中不易理解的事情是,在您的侦听器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)
}
}
Run Code Online (Sandbox Code Playgroud)