akka.io在2.3中逐行接收

时间:2015-05-26 19:37:53

标签: scala tcp akka

我正在使用Akka 2.3(因为那是Play附带的版本),并希望连接到某个TCP套接字。我知道akka.io包。但是,我无法看到以UTF-8字符串逐行处理接收数据的任何方法(仅针对接收字节块)。

在网上搜索有很多关于Akka 2.2的实验Pipeline API的参考资料。但是这个API再次在Akka被删除了。

我在寻找的是大多数缓冲类中的readLine,但是对于Akka I / O Framework。

2 个答案:

答案 0 :(得分:1)

Akka Stream似乎很有希望,但是由于它还没有发布,我决定自己实现它,只需简单地联系缓冲区中的所有数据并等待分隔符字符。

  private val separatorBytes = // like CRLF
  private var buffer = ByteString.empty
  private var nextPossibleMatch = 0

  // when receiving chunks of bytes they are appended to buffer and doParseLines is executed

  private def doParseLines(parsedLinesSoFar: Vector[String] = Vector()): Vector[String] = {
    val possibleMatchPos = buffer.indexOf(separatorBytes.head, from = nextPossibleMatch)
    if (possibleMatchPos == -1) {
      parsedLinesSoFar
    } else {
      if (possibleMatchPos + separatorBytes.size > buffer.size) {
        nextPossibleMatch = possibleMatchPos
        parsedLinesSoFar
      } else {
        if (buffer.slice(possibleMatchPos, possibleMatchPos + separatorBytes.size) == separatorBytes) {
          // Found a match
          val parsedLine = buffer.slice(0, possibleMatchPos).utf8String
          buffer = buffer.drop(possibleMatchPos + separatorBytes.size)
          nextPossibleMatch -= possibleMatchPos + separatorBytes.size
          doParseLines(parsedLinesSoFar :+ parsedLine)
        } else {
          nextPossibleMatch += 1
          doParseLines(parsedLinesSoFar)
        }
      }
    }
  }

答案 1 :(得分:0)

旧流水线的替换是Akka Streams,它提供了流式 TCP实施。可以在这样的流中添加行解析器,以便轻松获得“行流”。

内置行解析器很快就会合并+str #17310: Basic framing support。目前,行解析器是一个可以粘贴到项目中的食谱:Akka Streams Cookbook: Parsing lines from ByteStrings

我建议您先阅读Working with Streaming IO文档然后修改示例,使其与您的用例匹配(使用parseLines食谱配方)。

请注意,Akka Streams仍处于试验阶段,API可能略有变化。 另一个重要信息是它们实现了www.reactive-streams.org规范,因此您可以开箱即用,而无需手动担心: - )