简体   繁体   English

在参与者之间发送Akka HttpEntity

[英]Sending Akka HttpEntity between actors

In akka-http, HttpRequest and HttpResponse are mostly immutable objects, except for their HttpEntity bodies (which have a Source ). 在akka-http中, HttpRequestHttpResponse大多是不可变的对象,除了它们的HttpEntity主体(具有Source )。

Is it safe to send a request, response, or solo entity to another actor (especially a remote actor) or is some precaution needed? 向其他参与者(尤其是远程参与者)发送请求,响应或单独实体是否安全?是否需要采取一些预防措施?

As stated in the comments: sending an HttpEntity to a remote Actor is unlikely to work due to the socket limitation. 如评论中所述:由于套接字限制,向远程Actor发送HttpEntity不太可能。 Further evidence can be found in the documentation (emphasis theirs): 可以在文档中找到更多证据(重点是它们):

IMPORTANT : Messages can be any kind of object but have to be immutable. 重要信息 :消息可以是任何类型的对象,但必须是不可变的。 Scala can't enforce immutability (yet) so this has to be by convention. Scala尚不能强制执行不变性,因此必须按照惯例进行。

However, the ByteString values coming from the Source do not have the same limitations as the Source itself since ByteString is immutable. 但是,由于ByteString是不可变的,因此来自SourceByteString值没有与Source本身相同的限制。 You could simply drain the Source on the local akka-http ActorSystem and dispatch ByteString values to your remote Actor. 您可以简单地在本地akka-http ActorSystem上消耗Source并将ByteString值分派到远程Actor。

As an example, say you want to use an Actor to uppercase all of the characters in a utf-8 based HttpEntity. 例如,假设您要使用Actor将基于utf-8的HttpEntity中的所有字符大写。 You can setup your Actor: 您可以设置演员:

class UpperActor extends Actor {
  override def receive : Receive = {
    case b : ByteString => sender() ! b.toString.toUpperCase
  }
}

Then your akka-http could look like: 然后您的akka​​-http可能看起来像:

val actorRef = ??? //setup the ref to remote UpperActor

/**Query the Actor*/
val dispatchByteString : (ByteString) => Future[String] = 
  (byteString : ByteString) => (actorRef ? byteString).mapTo[String]

val parallelism = 10 // should match your Actor's mailbox size

/**Construct the Response Source.*/
val requestToSrc : (HttpRequest) => Source[ChunkStreamPart,_] = 
  (_ : HttpRequest).entity
                   .dataBytes
                   .mapAsync(parallelism)(dispatchByteString)
                   .map(ChunkStreamPart.apply)

val contentType = ContentTypes.`text/plain(UTF-8)`

val route = extractRequest { request =>
  complete(HttpResponse(entity = Chunked(contentType, requestToSrc(request))))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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