新的Akka I / O(Java)如果可能,使用ByteIterator进行TCP数据处理需要一个java示例

时间:2013-03-25 15:11:03

标签: java tcp io akka

我正在尝试使用新的Akka I / O实现Tcp服务器,遗憾的是文档尚未完成,我在java中实现它时遇到了一些问题:(。 我设法创建了一个客户端和服务器,并从客户端向服务器发送消息, 但是如何使用ByteIterator读取收到的字节? 我有错误的推荐吗?也许这不是你处理数据的方式。

当我快速发送大量消息时,会发生一些奇怪的事情,它们都排队到bi,并且在我创建它之后数据永远不会重置事件.getInt()

 if (msg instanceof Tcp.Received) {
   final Tcp.Received recv = (Tcp.Received) msg;
   final ByteString data = recv.data();
   ByteIterator bi = data.iterator();
   while(bi.hasNext()) {
      ....
   }
 } else if (msg instanceof Tcp.CommandFailed) {
   final Tcp.CommandFailed failed = (Tcp.CommandFailed) msg;
   final Tcp.Command command = failed.cmd();
   // react to failed connect, bind, write, etc.
 } else if (msg instanceof Tcp.ConnectionClosed) {
   final Tcp.ConnectionClosed closed = (Tcp.ConnectionClosed) msg;
   if (closed.isAborted()) {
      // handle close reasons like this
 }

解决方案: 哦!现在我理解了我的错误,我在客户端缓存了byteStringBuilder,忘了清除它-_-多么愚蠢!

对于那些想要实现Java实例的人来说,我就是这样做的:

如果你们有任何优化,我可以服用它们!:)

   int packetSize = 0;
   if (msg instanceof Tcp.Received) {
        final Tcp.Received recv = (Tcp.Received) msg;
        final ByteString data = recv.data();
        ByteIterator bi = data.iterator();
        while (bi.hasNext()) {
            packetSize = bi.getInt(ByteOrder.LITTLE_ENDIAN);
            Message m = Message.fromByteIterator(bi);
            getContext().parent().tell(m, null);
        }

    }

Message.fromByteIterator(bi)将通过从BI中获取Ints,Floats,Bytes Arrays ...来初始化新的消息对象

1 个答案:

答案 0 :(得分:0)

我不完全确定我理解这个问题,但是有两个问题可能导致这个问题。

您收到的ByteString包含Tcp提供的块。你得到的迭代器只会迭代该块。它不是一个流,只是一个块。此外,Tcp可以决定在您想要的任何地方拆分您的字节流,因此您获得的块可能与您的消息边界不一致。你必须自己处理框架。

如果发送速度过快而网络无法跟上,则可能会出现第二个问题。 Akka IO具有内置的流量控制机制。最简单的情况是在每个Write上附加一个Ack对象,只有在前一个写入被激活时才发送下一个写入。