2

我使用 Netty 实现了代理服务器,我在其中解码 HTTP 请求,然后根据它们的路径将这些请求写入传出通道。我需要从 HTTP 请求的内容中提取一些信息以供将来处理(基本上,找到“request-id:”形式的子字符串并记录以备后用。这样做的最佳方法是什么?显然,我可以将通道缓冲区的内容转储到字符串中并使用标准的 java 字符串搜索技术,但是在 netty 中是否有一种直接且开销低的方法来执行此操作,而无需创建新字符串?例如,如果有类似asCharSequence(CharSet)ChannelBuffer 的方法,我可以只使用 java Pattern/Matcher。

4

3 回答 3

2

不久前,当我试图嗅探 ChannelBuffer 中包含的字节的内容类型时,我遇到了这个问题。

我想到你可能会使用:

channelBuffer.toByteBuffer().asCharBuffer()

然后您可以将其传递给正则表达式 Pattern.Matcher,因为这不会重新分配缓冲区,而是按原样包装和重新表示。但这不起作用,因为 CharBuffer 需要进行 Charset.decoded,这可能与将 ChannelBuffer 转换为字符串一样糟糕。

ChannelBufferIndexFinder的一个问题是它在搜索一个特定字节时往往效果最好,而当你搜索一个字符串(或更基本上是长度> 1的字节数组)时,我无法让它工作我想要的方式。

我开始研究这个名为ByteSequenceIndexFinder的 ChannelBufferIndexFinder 实现,它有助于在 ChannelBuffer 中找到实际的字节序列,但它有几个问题:

  1. 由于ChannelBuffer.bytesBefore(...)的工作方式,它不返回定位数组的直接偏移量,而是返回它的结尾,因此您必须从返回的索引中减去字节数组长度 +1才能获得字节缓冲区中字节序列开始的偏移量。
  2. 由于查找器必须保持状态(到目前为止匹配的字节数),它不是线程安全的。我尝试用 ThreadLocal 替换(一个 int 的)简单状态,但性能大大降低,但它仍然是一种选择。

实际上有一个替代调用方法是非标准的,它解决了问题 #1,它的工作方式如下:

ChannelBuffer bufferToSearch = ...;
String searchStr = "....";
ByteSequenceIndexFinder finder = new ByteSequenceIndexFinder(searchStr.getBytes());
int startingOffset = finder.findIn(bufferToSearch);

该startingOffset 是通道缓冲区内匹配字节序列的第一个字节的偏移量。

如果您需要这样的东西,希望它对您有所帮助。是它的测试用例的开始。

于 2013-05-02T14:36:22.673 回答
0

你不能使用 ChannelBuffer.indexOf(...) 并将 ChannelBufferIndexFinder 传递给方法吗?

http://netty.io/3.6/api/org/jboss/netty/buffer/ChannelBuffer.html#indexOf(int,%20int,%20org.jboss.netty.buffer.ChannelBufferIndexFinder)

于 2013-04-30T19:01:52.027 回答
0

我正在使用以下实现ChannelBufferIndexFinder来搜索字符串ChannelBuffer

public class StringFinder implements ChannelBufferIndexFinder {

    private String string;

    public StringFinder(String string) {
        this.string = string;
    }

    @Override
    public boolean find(ChannelBuffer buffer, int guessedIndex) {

        if (buffer.writerIndex() - guessedIndex < string.length()) {
            return false;
        }

        return string.equals(buffer.toString(guessedIndex,
                string.length(), Charset.defaultCharset()));
    }

}
于 2015-10-25T23:52:05.163 回答