0

Nettyを使用していますが、キャリッジリターンを受信しない限り、ChannelPipelineのFrameDecoderは呼び出されないようです。たとえば、完全なJSON文字列が受信されたことを検出するために作成した次のデコーダーがあります。

public class JsonDecoder extends FrameDecoder {
    @Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) {
        char inChar = 0;
        ChannelBuffer origBuffer = buf.copy();
        StringBuilder json = new StringBuilder();
        int ctr = 0;
        while(buf.readable()) {
            inChar = (char) buf.readByte();
            json.append(inChar);
            if (inChar == '{') {
                ctr++;
            } else if (inChar == '}') {
                ctr--;
            }
        }
        if (json.length() > 0 && ctr == 0) {
            return origBuffer;
        } 
        buf.resetReaderIndex();
        return null;
    }
}

(ややずさんなコードはご容赦ください。これは、Nettyを使用した最初の試みであり、少しの学習経験があります。)

telnetを使用してサーバーに接続し、有効なJSONを貼り付けて、Returnキーを押してテストすると、これは正常に機能することがわかります。ただし、JSON文字列の最後の終了'}'の後でreturnキーを押さないと、デコーダーは更新されたバッファーで呼び出されません。

異なる動作をするようにチャネルパイプラインを構成する方法はありますか?私はこれをグーグルで検索し、Nettyのドキュメントを調べました。基本的なものが欠けているような気がして、正しい場所を探したり、正しいものを探したりしていません。助けてくれてありがとう。

4

2 に答える 2

1

お使いの telnet クライアントは、完了した行のみがサーバーに送信される「古い行単位」モードに戻っていますか ( telnet のマニュアル ページ)? 代わりに、単純な Java クライアントを作成してメッセージを送信してみてください。

于 2013-03-23T12:50:49.640 に答える
1

JSON ストリームの読み取りは、HTTP ストリームの読み取りに似ていると思います。なぜなら、開き括弧と閉じ括弧を追跡する必要があるからです (JSON 文字列が配列である場合は、括弧も同様です)。HTTP デコーダーのソースを見ると、ReplayingDecoder を使用していることがわかります。再生デコーダーを使用する必要はありませんが、メッセージ全体が複数のバッファーに分割されている場合は非常に役立ちます。

FrameDecoders は、特殊文字 (したがってデコーダーの名前) で「フレーム化」されているか、長さフィールドが先頭に追加されているメッセージを読み取るためのものです。

また、DecoderEmbedder ヘルパー クラスを使用することを強くお勧めします。これにより、実際の I/O を実行せずに JSON デコーダーを単体テストできます。

于 2013-03-23T12:59:09.250 に答える