tomite
tomite

Reputation: 15

How to use actor to receive http requests and requests from other actors?

I want TestHttp class to be able to receive http requests or messages from other actors. How can I do it?

Code:

object Main extends App with SimpleRoutingApp {
  implicit val system = ActorSystem("system")
  import system.dispatcher
  implicit val timeout = Timeout(240.seconds)

  startServer(interface = "localhost", port = 3000) {
    get {
      path("register" / IntNumber) { n =>
        respondWithMediaType(MediaTypes.`application/json`) { ctx =>
          val future = IO(Http) ? Bind(system.actorOf(Props[TestHttp]), interface = "localhost", port = 3000 + n)
          future onSuccess {
            case Http.Bound(msg) => ctx.complete(s"Ok:"+msg)
            case _ => ctx.complete("...")
          }
        }
      } // : Route == RequestContext => Unit
    } // : Route
  }
}

trait TestHttpService extends HttpService {
  val oneRoute = {
        path("test") {
          complete("test")
        }
  }
}

class TestHttp extends Actor with TestHttpService {
  def actorRefFactory = context
  val sealedRoute = sealRoute(oneRoute) 
    def receive = {
      // case HttpRequest(GET, Uri.Path("/ping"), _, _, _) => //not working
      //   sender ! HttpResponse(entity = "PONG")
      case ctx: RequestContext => sealedRoute(ctx) //not working

    } 
  // def receive = runRoute(oneRoute) //it works
}

Upvotes: 1

Views: 267

Answers (1)

abatyuk
abatyuk

Reputation: 1342

Actor.Receive is a partial function that takes Any value and returns Unit (PartialFunction[Any, Unit]), so you can do it by regular PF composition.

HttpService.runRoute returns Actor.Receive (see https://github.com/spray/spray/blob/master/spray-routing/src/main/scala/spray/routing/HttpService.scala#L31)

So, your solution would be:

class TestHttp extends Actor with TestHttpService {
  def actorRefFactory = context
  val sealedRoute = sealRoute(oneRoute) 
    def receive = {
        case s: String => println(s"Just got string $s")
    } orElse runRoute(oneRoute)
}

Upvotes: 4

Related Questions