简体   繁体   中英

spray-can simple-http-server example how are Bound messages handled?

In the spray-can HTTP server example, when I run the server, I don't see any "Bound" message showing up in the log:

https://github.com/spray/spray/tree/master/examples/spray-can/simple-http-server/src/main

However, if I try to create my own server, and ignore the Bound message I get them going to dead-letters:

$ sbt run
[info] Set current project to pingpong (in build file:/D:/Projects/pingpong/)
[info] Updating {file:/D:/Projects/pingpong/}pingpong...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Running drozdyuk.pingpong.Main
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8081
[INFO] [08/03/2015 20:05:47.246] [default-akka.actor.default-dispatcher-2] [akka
://default/deadLetters] Message [akka.io.Tcp$Bound] from Actor[akka://default/us
er/IO-HTTP/listener-0#-892116855] to Actor[akka://default/deadLetters] was not d
elivered. [1] dead letters encountered. This logging can be turned off or adjust
ed with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letter
s-during-shutdown'.

My question is mainly out of curiosity, how does the Bound message get handled in the example? Is it some kind of logging that swallows them or something else?

Code for my Main.scala :

package drozdyuk.pingpong

import akka.actor.{ActorSystem, Props}
import akka.io.IO
import spray.can.Http

object Main extends App {
  implicit val system = ActorSystem()

  // the handler actor replies to incoming HttpRequests
  val handler = system.actorOf(Props[WebService], name = "handler")

  val PORT = 8081
  val DOMAIN = "localhost"
  IO(Http) ! Http.Bind(handler, interface = DOMAIN, port = PORT)
}

and my WebService.scala :

package drozdyuk.pingpong

import akka.actor._
import spray.http.HttpMethods.{GET}
import spray.can.Http
import spray.http.{HttpRequest, HttpResponse, Uri}

class WebService extends Actor with ActorLogging {
    def receive = {
      // New connection - register self as handler
      case _: Http.Connected => sender ! Http.Register(self)

      case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
        sender ! HttpResponse(entity = "pong")

      case HttpRequest(GET, Uri.Path("/pong"), _, _, _) =>
        sender ! HttpResponse(entity = "ping")


      case _: HttpRequest => sender ! HttpResponse(status = 404, entity = "Unknown resource!")


    }
}

You could use another version of tell in your Main :

IO(Http).tell(Http.Bind(handler, interface = DOMAIN, port = PORT), sender = handler)

And then handle Bound message in your WebService:

class WebService extends Actor with ActorLogging {
    def receive = {
        case Http.Bound(address) =>
        //all other cases...
    }
}

In your case you are using

def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit

and there is no implicit sender in scope of Main so default noSender will be used.

I tried this and it works great for me:

import akka.actor._
import akka.io._
import spray.can.Http
import spray.http.HttpResponse
import spray.http.HttpRequest
import spray.http.Uri
import spray.http.HttpMethods.{GET}

class WebService extends Actor with ActorLogging {
    def receive = {
        case _: Http.Connected => sender ! Http.Register(self)

        case _: HttpRequest => sender ! HttpResponse(status = 404, entity =     "Unknown resource!")

        case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
                    sender ! HttpResponse(entity = "pong")

        //all other cases...
    }
}

object TestSpray extends App {
    implicit val system = ActorSystem()
    val myListener: ActorRef = system.actorOf(Props[WebService], name = "handler")
    IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM