为什么 ChannelHandlerContext.writeAndFlush() 不处理我的字符串?
Why is ChannelHandlerContext.writeAndFlush() not processing my string?
我正在使用 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);
}
}
}
我的 ChannelHandlerContext.writeAndFlush(String msg) 失败了,原因是
java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)
根据我对文档和示例的理解,writeAndFlush 应该向管道写入一个字符串,并且字符串编码器应该将该字符串更改为 bytebuf,然后再将其转发到套接字进行传输。
我检查了通道管道,StringEncoder 肯定在那里注册。我试过通过 Netty 库遵循执行路径,但那是疯狂的方式。
我使用了错误的 write 电话吗? writeAndFlush 是否跳过了 StringEncoder?我应该放弃编程并回到碰撞测试假人的工作吗?
我想你想用Channel.writeAndFlush
来确保你走完整个ChannelPipeline
。您很可能使用 ChannelHandlerContext
或 ChannelHandler
放在 StringEncoder
之前,因此不会被它处理。
我正在使用 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);
}
}
}
我的 ChannelHandlerContext.writeAndFlush(String msg) 失败了,原因是
java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)
根据我对文档和示例的理解,writeAndFlush 应该向管道写入一个字符串,并且字符串编码器应该将该字符串更改为 bytebuf,然后再将其转发到套接字进行传输。 我检查了通道管道,StringEncoder 肯定在那里注册。我试过通过 Netty 库遵循执行路径,但那是疯狂的方式。 我使用了错误的 write 电话吗? writeAndFlush 是否跳过了 StringEncoder?我应该放弃编程并回到碰撞测试假人的工作吗?
我想你想用Channel.writeAndFlush
来确保你走完整个ChannelPipeline
。您很可能使用 ChannelHandlerContext
或 ChannelHandler
放在 StringEncoder
之前,因此不会被它处理。