Scala Akka http丢失发送方引用

Scala Akka http丢失发送方引用,scala,akka,akka-http,Scala,Akka,Akka Http,在收到未来[httpResponse]后,我试图将消息发送给发件人,但我失去了发件人的引用 以下是我的接收方法的代码: def receive = { case Seq(method: HttpMethod, endpoint: String, payload: String) ⇒ { // I have the correct sender reference implicit val materializer: ActorMat

在收到
未来[httpResponse]
后,我试图将消息发送给
发件人
,但我失去了
发件人的引用

以下是我的接收方法的代码:

    def receive = {
        case Seq(method: HttpMethod, endpoint: String, payload: String) ⇒ {
          // I have the correct sender reference
          implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system)) // needed by singleRequest method below
          // I have the correct sender reference

          val response: Future[HttpResponse] = Http(context.system).singleRequest(HttpRequest(method = method, uri = endpoint, entity = payload))
          println("http request sent")
          // I have the correct sender reference
          response onSuccess {
            case HttpResponse(statusCode, _, entity, _) ⇒ {
              entity.dataBytes.runFold(ByteString.empty)(_ ++ _).foreach { body ⇒ 
                // NO Reference to sender
                sender ! HttpConsumerResponse(statusCode = statusCode, contentType = entity.contentType, body = body.utf8String)
              }
            }
            case _ => println("http request success 2")
          }

          response onFailure {
            case exception: Throwable ⇒ {
              println("http request failure")
              throw exception
            } // Adopting let-it-crash fashion by re-throwning the exception
          }
        }
        case _ => println("I am httpConsumerActor and I don't know")
      }
如果我这样更改代码:

def receive = {
        case Seq(method: HttpMethod, endpoint: String, payload: String) ⇒ {
          // I have the correct sender reference
          implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system)) // needed by singleRequest method below
          // I have the correct sender reference

          val response: Future[HttpResponse] = Http(context.system).singleRequest(HttpRequest(method = method, uri = endpoint, entity = payload))
          println("http request sent")
          // I have the correct sender reference
          val mySender = sender
          response onSuccess {
            case HttpResponse(statusCode, _, entity, _) ⇒ {
              entity.dataBytes.runFold(ByteString.empty)(_ ++ _).foreach { body ⇒ 
                // NO Reference to sender
                mySender ! HttpConsumerResponse(statusCode = statusCode, contentType = entity.contentType, body = body.utf8String)
              }
            }
            case _ => println("http request success 2")
          }

          response onFailure {
            case exception: Throwable ⇒ {
              println("http request failure")
              throw exception
            } // Adopting let-it-crash fashion by re-throwning the exception
          }
        }
        case _ => println("I am httpConsumerActor and I don't know")
      }
一切正常,但我必须发送演员的推荐信,就像这句话一样,我知道这不是最好的方式:

val mySender = sender

第一种方法不起作用的原因是您正在“关闭可变状态”,即执行onComplete时执行
sender()
方法,并且不再包含引用。这在阿克卡是一个相当常见的错误,我们都有过

正确的解决方案,正如您自己已经发现的,是预先存储引用。还有其他选择,例如“成为”其他东西,但对于您的使用,我想说的是,就“好”和“简单”之间的权衡而言,pre-store是正确的方法


有关参考资料,请参阅以下参考资料:,

其他参考资料,Akka文档: