Akka http丢失发件人参考

Jea*_*ean 2 scala akka akka-http

收到一个Future[httpResponse]我试图发送消息后,sender但我失去了参考sender.

这是我的接收方法的代码:

    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")
      }
Run Code Online (Sandbox Code Playgroud)

如果我改变这样的代码:

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")
      }
Run Code Online (Sandbox Code Playgroud)

一切正常,但我必须发送演员的引用,就像这一行,我知道这不是最好的方法:

val mySender = sender
Run Code Online (Sandbox Code Playgroud)

Die*_*oia 6

你的第一种方法不起作用的原因是你正在"关闭可变状态",即该sender()方法在执行onComplete时执行,并且不再包含引用.这是阿卡的一个相当常见的错误,我们都去过那里!:)

正如您已经发现的那样,正确的解决方案是预先存储引用.还有其他选择,比如"成为"别的东西,但是对于你的使用我会说,在"好"和"简单"之间的权衡方面,预售是正确的方法.

供参考,请参阅以下资源:SO问题,博客文章