我想为netty聊天程序的所有消息添加固定或可变长度标头。
我正在建立一个简单的聊天;所有消息(当前)都使用LengthFieldPrepender
和LengthFieldBasedFrameDecoder
length 分隔,长度部分为2个字节,到目前为止这个工作正常:
+-------------+-------------------+
| <length> | <message> |
| 13 | 'Yo, waz up?' |
+-------------+-------------------+
..和管道
//inbound
pipeline.addLast(new LengthFieldBasedFrameDecoder (1024,0,2,0,2));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
//outbound
pipeline.addLast(new LengthFieldPrepender(2));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
目标是添加包含应用名称+版本的固定或变量标头,以过滤掉无效消息;此示例使用标头'nChat v1.0'
,固定长度为10个字节:
--------------+--------------+-------------------+
| <length> | <header> | <message> |
| 23 | 'nChat v1.0' | 'Yo, waz up?' |
--------------+--------------+-------------------+
调整入站管道以容纳标题应该不是问题,但我不希望标题被剥离,所以我将initialBytesToStrip
留在了2
:
pipeline.addLast(new LengthFieldBasedFrameDecoder (1024,0,2,0,2));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
我不确定在邮件中添加标头的最佳方法是什么。我假设需要自定义处理程序;脑海中浮现出两个想法:
StringEncoder
,将标头添加到外发邮件中,照常编码。LengthFieldPrepender
out.writeBytes("nChat v1.0".getBytes())
,序列化标题
我怀疑后一种选择是正确的,因为标题在本质上与它正在做的事情上的LengthFieldPrepender
没有区别。
答案 0 :(得分:0)
这是我想出的;它支持可变长度标头。我仍然是一个n00b,欢迎评论:-D
public class HeaderFieldEncoder extends MessageToByteEncoder<ByteBuf> {
public HeaderFieldEncoder(String header){
this.header = header;
}
@Override
protected void encode(
ChannelHandlerContext ctx,
ByteBuf msg,
ByteBuf out
)throws Exception {
//header = "nChat v1.0"
ByteBuf headerBuf = Unpooled.copiedBuffer(
header.getBytes(charset));
out.writeBytes(headerBuf);
out.writeBytes(msg, msg.readerIndex(), msg.readableBytes());
}
}
public class HeaderFieldDecoder extends MessageToMessageDecoder<ByteBuf> {
public HeaderFieldDecoder(String header){
this.header = header;
}
@Override
protected void decode(
ChannelHandlerContext ctx,
ByteBuf msg,
List<Object> out
)throws Exception {
String extractedHeader = extractHeader(msg);
//if desired, validate header
//if(!header.equals(extractedHeader)
String content = msg.toString(charset);
out.add(content);
}
private String extractHeader(ByteBuf msg){
String headerField = null;
if(msg.readableBytes() >= header.length()){
byte[] headerBytes = new byte[header.length()];
msg.readBytes(headerBytes, 0, header.length());
headerField = new String(headerBytes, charset);
}
return headerField;
}
}
工作渠道:
String header = "nChat v1.0";
//INBOUND
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024,0,2,0,2));
pipeline.addLast(new HeaderFieldDecoder(header));
pipeline.addLast(new StringDecoder());
//OUTBOUND
pipeline.addLast(new LengthFieldPrepender(2));
pipeline.addLast(new HeaderFieldEncoder(header));
pipeline.addLast(new StringEncoder());
你怎么看;这有效吗?我是否正确清理资源?