问题描述:

Here is my previous question: Send data from InputStream over Akka/Spring stream

I have managed to send compressed and encrypted file over Akka stream. Now, I am looking for way to transport metadata along with data, mainly filename and hash (checksum).

My current idea is to use Flow.prepend function and insert metadata before data this way:

  1. filename, that can vary in size but always ends with null byte

  2. fixed size hash (checksum)

  3. data

Then, on receiving end I would have to use Flow.takeWhile twice - once to read filename and second time to read hash, and then just read data. It doesn't really look like elegant solution plus if in future I would like to add more metadata it will become even worse.

I have noticed method Flow.named, however documentation says just:

Add a ``name`` attribute to this Flow.

and I do not know how to use this (and if is it possible to transport filename over it).

Question is: is there better idea to transport metadata along with data over Akka stream than above?

EDIT: Attaching my drawing with idea.

网友答案:

I think prepending the metadata makes sense. A simple approach could be to prepend the metadata using the same framing you use to send the data.

The receiving end will need to know how many metadata blocks are there, and use this information to split it. See example below.

// client end
filenameSrc
  .concat(hashSrc)
  .concat(dataSrc)
  .via(Framing.delimiter(ByteString("\n"), Int.MaxValue, allowTruncation = true))
  .via(Tcp().outgoingConnection(???, ???))
  .runForeach{ ??? }

// server end
val printMetadata =
  Flow.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>
    import GraphDSL.Implicits._

    val metadataSink = Sink.foreach(println)
    val bcast = builder.add(Broadcast[ByteString](2))

    bcast.out(0).take(2) ~> metadataSink

    FlowShape(bcast.in, bcast.out(1).drop(2).outlet)
  })

val handler =
  Framing.delimiter(ByteString("\n"), Int.MaxValue)
  .via(printMetadata)
  .via(???)

This is only one of the many possible approaches to solve this. But whatever solution you choose, the receiver will need to have knowledge of how to extract the metadata from the raw stream of bytes it reads over TCP.

相关阅读:
Top