加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用scala akka spray进行非常基本的http服务器测试时出错

发布时间:2020-12-16 10:04:50 所属栏目:安全 来源:网络整理
导读:我做了一个非常基本的喷雾测试,使用: Akka 2.10 2.24 Scala 2.10.3 喷雾罐1.3.1 sbt 0.13 IntelliJ 13 这是我的代码: val myListener: ActorRef = system.actorOf(Props[TestHttpListener],"httpListener")IO(Http) ! Http.Bind(myListener,interface = "l
我做了一个非常基本的喷雾测试,使用:

> Akka 2.10 2.24
> Scala 2.10.3
>喷雾罐1.3.1
> sbt 0.13
> IntelliJ 13

这是我的代码:

val myListener: ActorRef = system.actorOf(Props[TestHttpListener],"httpListener")
IO(Http) ! Http.Bind(myListener,interface = "localhost",port = 8080)

httpListener使用Http.Register(self)对Http.Connected作出反应.

我使用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中.收到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,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)
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读