首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >识别Akka HttpRequest和HttpResponse?

识别Akka HttpRequest和HttpResponse?
EN

Stack Overflow用户
提问于 2018-05-27 21:32:26
回答 2查看 516关注 0票数 1

在使用Akka HttpRequest并将请求传递给参与者时,我无法识别响应。参与者将处理将接收到的每条消息,但它不知道用于获取此响应的请求。是否有任何方法来识别与响应匹配的每个请求?

注意:我没有服务器再次重新发送请求体的任何部分。

提前感谢

MySelf.scala

代码语言:javascript
运行
复制
import akka.actor.{ Actor, ActorLogging }
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.{ ActorMaterializer, ActorMaterializerSettings }
import akka.util.ByteString

class Myself extends Actor with ActorLogging {

import akka.pattern.pipe
import context.dispatcher

final implicit val materializer: ActorMaterializer = 
       ActorMaterializer(ActorMaterializerSettings(context.system))

def receive = {
  case HttpResponse(StatusCodes.OK, headers, entity, _) =>
    entity.dataBytes.runFold(ByteString(""))(_ ++ _).foreach { body =>
      log.info("Got response, body: " + body.utf8String)
  }
  case resp @ HttpResponse(code, _, _, _) =>
    log.info("Request failed, response code: " + code)
    resp.discardEntityBytes()
  }

}

Main.scala

代码语言:javascript
运行
复制
import akka.actor.{ActorSystem, Props}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer

object HttpServerMain extends App {

import akka.pattern.pipe

//  import system.dispatcher
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
// needed for the future flatMap/onComplete in the end
implicit val executionContext = system.dispatcher

val http = Http(system)

val myActor = system.actorOf(Props[MySelf])

http.singleRequest(HttpRequest(uri = "http://akka.io"))
    .pipeTo(myActor)

http.singleRequest(HttpRequest(uri = "http://akka.io/another-request"))
    .pipeTo(myActor)
Thread.sleep(2000)
system.terminate()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-27 22:40:17

您可以简单地使用map转换Future,并在将其输送到myActor之前向其添加某种ID (通常称为关联ID )。

代码语言:javascript
运行
复制
http.singleRequest(HttpRequest(uri = "http://akka.io"))
    .map(x => (1, x)).pipeTo(myActor)

您需要更改模式匹配块以获取tupple:

代码语言:javascript
运行
复制
case (id, HttpResponse(StatusCodes.OK, headers, entity, _)) =>

如果由于某种原因不能/不想更改模式匹配块,则可以使用相同的方法,而是在已完成的请求(使用copy)中添加一个唯一的HTTP头,其内容如下(如果编译时不选中):

代码语言:javascript
运行
复制
// make a unique header name that you are sure will not be
// received from http response:
val correlationHeader: HttpHeader = ... // mycustomheader

// Basically hack the response to add your header:
http.singleRequest(HttpRequest(uri = "http://akka.io"))
    .map(x => x.copy(headers = correlationHeader +: headers)).pipeTo(myActor)

// Now you can check your header to see which response that was:
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
  headers.find(_.is("mycustomheader")).map(_.value).getOrElse("NA")

与以前的选项相比,这更像是一次黑客攻击,因为您正在修改响应。

票数 1
EN

Stack Overflow用户

发布于 2018-05-27 22:55:06

我认为您不能直接使用pipeTo来实现这一点,因为它实际上只是对您的Futureadds andThen调用。一个选项是map,然后将一个(request, response)元组发送给参与者:

代码语言:javascript
运行
复制
val request = HttpRequest(uri = "http://akka.io")
http.singleRequest(request).map {
  response => myActor ! (request, response)
}

class Myself extends Actor with ActorLogging {
  ...
  def receive = {
    case (request, HttpResponse(StatusCodes.OK, headers, entity, _)) =>
      ...

    case (request, resp @ HttpResponse(code, _, _, _)) =>
      log.info(request.toString)
      ...
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50556694

复制
相关文章

相似问题

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