当前位置: 首页 > 知识库问答 >
问题:

为什么是ChannelHandlerContext。writeAndFlush()不处理我的字符串?

凌琦
2023-03-14

我使用Netty 4.1.16创建一个服务器。我建立一个管道:

socketChannel.pipeline()
        //Line Based Frame Decoder will split a message into frames separated by CR/LF.
        // This one discards the delimiter and fails on excessive length only when the
        // entire frame has been read.
        .addLast("Frame Decoder", new LineBasedFrameDecoder(MAX_FRAME_LENGTH, true, false))
        // String decoder changes inbound byte stream into a string.
        .addLast("String Decoder", new StringDecoder(CharsetUtil.US_ASCII))
        // VoiceMessage is a custom decoder that turns a string into a socket message
        // and passes it to a command handler thread.
        .addLast("VoiceMessage Decoder", new InboundVoiceHandler())
        // String encoder allows us to write a string directly to the channel without needing
        // to write a custom string-to-byte encoder.
        .addLast("String Encoder", new StringEncoder(CharsetUtil.US_ASCII));

在稍后的代码中,我将创建一个对传入消息的字符串响应,并尝试使用以下命令将其写入ChannelHandlerContext:

    message = pack.getBoardList() == null || pack.getBoardList().size() > 0
            ? "Existing pack number " + pack.getPackNo() + " has been recalled."
            : "New pack number " + pack.getPackNo() + " has been started.";
    new OutboundTalkmanMessage(channelHandlerContext, voiceMessage.getVoiceSession())
            .writeAndFlush(message, vdtsSysDB);

...

public class OutboundTalkmanMessage {
    private VoiceSession voiceSession;
    private ChannelHandlerContext ctx;

    private static final Logger LOG = LoggerFactory.getLogger(OutboundTalkmanMessage.class);

    public OutboundTalkmanMessage(ChannelHandlerContext ctx, VoiceSession voiceSession) {
        this.ctx = ctx;
        this.voiceSession = voiceSession;
    }

    public void writeAndFlush(String message, VdtsSysDB vdtsSysDB) {
        saveOutgoingMessage(message, vdtsSysDB);
        String talkmanMessage = "\"" + message + "\"\r\n\n";
        LOG.info("Ougoing message: [{}]", talkmanMessage);
        try {
            ChannelFuture channelFuture = ctx.writeAndFlush(talkmanMessage);
            LOG.info("Waiting for write.");
            channelFuture.addListener(future -> {
                if (future.isSuccess()) LOG.info("Write succeeded.");
                else {
                    LOG.error("Write failed. {}", future.cause());
                }
                LOG.info("Message sent.");
                ctx.close();
            });
        } catch (Exception e) {
            LOG.error("Error writing talkman output.", e);
        }
    }
}

我的通灵之手是背景。writeAndFlush(字符串消息)失败,原因是

java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)

正如我所理解的文档和示例,WriteAndFlush应该向管道写入一个字符串,并且字符串编码器应该在将该字符串转发到套接字进行传输之前将其更改为字节。我已经检查了通道管道,StringEncoder肯定是在那里注册的。我尝试过通过Netty库遵循执行路径,但这种方式是疯狂的。我是否使用了错误的写入呼叫?写和冲洗是否跳过StringEncoder?我应该放弃编程,回去做碰撞测试假人吗?

共有1个答案

邵捷
2023-03-14

我想你应该使用频道。writeAndFlush以确保您走完整个通道管道。您最有可能使用ChannelHandlerContextChannelHandler,它位于StringEncoder之前,因此不会被它处理。

 类似资料:
  • 我在Linux中使用的Java版本是: OpenJDK版本“16.0.2”2021-07-20 OpenJDK运行时环境(构建16.0.2+7) OpenJDK 64位服务器VM(构建16.0.2+7,混合模式) 这是我从Head-First Java书中编译的代码: 为什么那个特殊字符(%)会出现在字符串的末尾,我如何编写代码来去掉它?

  • 问题内容: 在.NET Framework 的参考中,使用type 声明请求类型。 在RFC 2616 中,声明了所有HTTP请求方法(例如POST,GET,PUT,DELETE …)。 .NET 和类中也存在类似的行为。 Java在方法上有类似的方法。 这些语言设计者为什么不考虑为这些HTTP方法实现枚举? 你有好主意吗? 问题答案: RFC 2616 链接的第一句话(添加了重点): HTTP

  • 我对字符编码的概念很困惑。 什么是Unicode、GBK等?编程语言如何使用它们? 我需要费心去了解他们吗?有没有一种更简单或更快的编程方法,而不必麻烦自己?

  • 我有一个变量,它保存表中的两个值(使用 ) 我进行了一次检查,以确保没有返回任何空值 但出于某种原因,即使应该只检查第一个字符/索引是否有空格,它也会输出" 没有价值 “条件结果…它应该输出 价值1,价值2 相反。。。 不仅如此,如果表列值为<code>NULL 为什么??

  • 问题内容: 好的,这很愚蠢,但是wtf还在继续吗? 我在Servlet中有一个String变量,它接受参数的值,并基于该值进行测试以执行某些操作,但是该方法不起作用。问题是什么? 在控制台上,System.out.println向我显示了动作的价值是“某物” 问题答案: 您的第二个比较是错误的。您还应该使用代替,例如: 该运算符比较 引用 的(字符串)对象和正常情况下 等于 字符串不自动具有相同的