首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用rest的Akka Actor热交换

使用rest的Akka Actor热交换
EN

Stack Overflow用户
提问于 2014-11-21 07:17:17
回答 2查看 1.6K关注 0票数 1

在调用rest时,我希望将参与者的路由切换到其他路由。请看下面的代码。

几个问题:

  1. 代码编译得很好,但当应用程序启动并进行http调用时,我得到配置的注册超时时间为1秒过期,停止消息,我没有从服务器得到任何响应。
  2. 我希望能够通过api将路由切换到另一组路由。

制造

代码语言:javascript
复制
package com.example
import akka.actor.Actor
import akka.io.IO
import spray.httpx.RequestBuilding._
import spray.http.MediaTypes._
import spray.routing.{RoutingSettings, RejectionHandler, ExceptionHandler, HttpService}
import spray.util.LoggingContext
import scala.concurrent.Future
import spray.can.Http
import spray.http._
import akka.util.Timeout
import HttpMethods._
import akka.pattern.ask
import akka.event.Logging
import scala.concurrent.duration._

case object Swap
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {

  implicit def actorRefFactory = context
  import context._

  def receive = {
      case Swap =>
           become {
             case Swap => unbecome()
             case _    => runRoute(otherRoutes)
           }
      case _ =>   runRoute(myRoute)
  } 
}


trait MyService extends HttpService { this: MyServiceActor =>

  implicit val timeout: Timeout = Timeout(15.seconds)

  implicit val system = context.system

  val myRoute =
  {
    path("") {
      get {
          complete("MyRoute")
      }
    } ~ path("swap") {

        get{
            self ! Swap
            complete("Swapped")
        }
    }
  }

  val otherRoutes =path("") {
  get {
      complete("OtherRoutes")
     }
   } ~ path("swap") {
        get{
        self ! Swap
        complete("Reverted")
     }
}

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-23 13:31:16

runRoute是一个部分应用的函数,所以不能只编写runRoute(routeName)来调用它--它只返回另一个函数(它处理路由),但不调用它;您应该显式地传递请求对象:

代码语言:javascript
复制
def receive = {
      case Swap =>
           become {
             case Swap => unbecome()
             case x    => val f = runRoute(otherRoutes); f(x)
           }
      case x => val f = runRoute(myRoute); f(x)
  } 

runRoute(route)返回处理“连接”消息的函数。这就是为什么您要获得“注册超时”错误--您不会从接收方法中返回这个函数。当您编写def receive = runRoute(route)时,这个函数被用作处理程序,一切都很好。但是当您编写def receive = {case _ => runRoute(route)}时,什么都不会发生-- receive函数什么也不做,因为runRoute(route)返回的函数什么也不做。

看,https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/HttpService.scala

而且,您也可以从您的路径调用变得/不再变,因为您已经将MyServiceActor作为自类型。当您使用单独的Swap消息时,参与者可能会在收到成功的“交换”响应后稍微改变角色(角色更改将异步发生)。

代码语言:javascript
复制
case object Swap
class MyServiceActor extends Actor with MyService with akka.actor.ActorLogging {

  implicit def actorRefFactory = context
  import context._

  def swapped = {
      case x => val f = runRoute(otherRoutes); f(x)
  }

  def receive = {
      case x => val f = runRoute(myRoute); f(x)
  } 
}


trait MyService extends HttpService { this: MyServiceActor =>

  implicit val timeout: Timeout = Timeout(15.seconds)

  implicit val system = context.system

  val myRoute = {
    pathSingleSlash {
      get {
            complete("MyRoute")
      }
    } ~ path("swap") {
        get {
            become(swapped)
            complete("Swapped")
        }
    }
  }

  val otherRoutes = { 
   pathSingleSlash {
     get {
      complete("OtherRoutes")
     }
   } ~ path("swap") {
     get{
        unbecome()
        complete("Reverted")
     }
   }
  }
}

更新:您的路径匹配程序也不正确。使用:

代码语言:javascript
复制
 pathSingleSlash {
   ...
 } ~ path("swap") {
     ...
 }

代码语言:javascript
复制
 path("swap") {
     ...
 } ~ path("") { //matches everything else
     ...
 } 

Updated2:

确保你的演员在你的主体中注册为单身人士:

代码语言:javascript
复制
import akka.io.IO
import spray.can.Http

implicit val system = ActorSystem()

val myListener: ActorRef = Props[MyServiceActor]

IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)

http://spray.io/documentation/1.1-SNAPSHOT/spray-can/http-server/#http-server

票数 2
EN

Stack Overflow用户

发布于 2021-04-21 06:58:36

我也面临同样的问题,那么您可以设置服务器段更大的位置来重新处理问题。

在这里输入代码

代码语言:javascript
复制
val backlog = 50000
val standardConfig = ServerSettings("spray.can.server.ssl-encryption = off, spray.can.server.registration-timeout = 5s")
val config = standardConfig.copy(serverHeader = "REST API", sslEncryption = false, remoteAddressHeader = true)
val serviceActor = system.actorOf(Props[ApiServiceActor], "apiServiceActor")
IO(Http) ? Http.Bind(serviceActor, interface = "0.0.0.0", ConfigurationHelper.Port, settings = Some(config), backlog = backlog)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27056058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档