我正在使用Akka 2.3(因为那是Play附带的版本),并希望连接到某个TCP套接字。我知道akka.io
包。但是,我无法看到以UTF-8字符串逐行处理接收数据的任何方法(仅针对接收字节块)。
在网上搜索有很多关于Akka 2.2的实验Pipeline API的参考资料。但是这个API再次在Akka被删除了。
我在寻找的是大多数缓冲类中的readLine
,但是对于Akka I / O Framework。
答案 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规范,因此您可以开箱即用,而无需手动担心: - )