0

I'm sending bytes as array of bytestrings through akka Source and Tcp, length of full array which includes: begin ++ len ++ gzip ++ sign ++ term is 997, but only 710 bytes reach the server. The code is here:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Source, Tcp}
import akka.util.ByteString
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}


class UpperServiceClient(ip: String, port: Int){
  def run = {
    implicit val system = ActorSystem("ClientSys")
    implicit val materializer = ActorMaterializer()

    ...
    // Initializing of (begin, len, gzip, sign, term) arrays
    ...

    val conn = Tcp().outgoingConnection(ip, port)
    val res: Future[ByteString] = Source(begin ++ len ++ gzip ++ sign ++ term).via(conn).
      runFold(ByteString.empty) { (acc, in) => acc ++ in }

    val resp = Await.result(res, 3.seconds)
  }
}

The server accepts and successfully processes first 710 bytes. There are no problems on server, cause when I'm trying send those bytes from another client the message comes complete. Any ideas with what the problem can be connected? Or may be somebody can advise how to split the message into two and send it through one connection?

  • Does any sub-combination of the arrays have a length of 710? In other words, is a whole array missing (e.g. maybe `begin ++ len ++ gzip ++ sign` is 710)? – Ramón J Romero y Vigil Aug 09 '18 at 11:17
  • No, all arrays have another size, and first 3 arrays come complete, but `sign` array comes cropped and the last array does not come at all. – alexandrgomd Aug 09 '18 at 13:39
  • What happens if you try increasing the result timeout to 5-8 seconds? – Markon Aug 10 '18 at 08:01
  • The same result. – alexandrgomd Aug 10 '18 at 08:51
  • 2
    Can you check with tcpdump or wireshark whether all bytes are sent or not? Even though it worked with another client, it might still be the case that there is some subtle (but correct) difference in behavior that triggers the server to stop reading too early? – Arnout Engelen Aug 10 '18 at 11:24

1 Answers1

0

A possible solution would be to construct the Source from Iterator values instead of Array values:

val sourceIterator : () => Iterator[ByteString] = 
  () => Iterable.apply(begin, len, gzip, sign, term)
                .map(_.iterator)
                .reduceLeftOption(_ ++ _)
                .getOrElse(Iterator.empty)

val byteStringSource : Source[ByteString,_] = Source fromIterator sourceIterator

If that doesn't work then I would guess that there is a configuration setting (in client akka, or client OS, or client network interface, ...) that is setting a limit for outbound message size...

Ramón J Romero y Vigil
  • 17,373
  • 7
  • 77
  • 125