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

在netty消息中添加固定或可变长度的标题

邰勇军
2023-03-14

我想为netty聊天程序的所有消息预先添加一个固定或可变长度的标题。

我正在建立一个简单的聊天;所有消息(当前)都使用LengthFieldPrependerLengthFieldBasedFrameDecoder进行长度分隔,长度部分为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("nChatv1.0". getBytes())

我怀疑后一个选项是正确的,因为标题在原则上与LengthFieldPrepender在所做的事情上没有什么不同。

共有1个答案

昌乐
2023-03-14

这是我想出来的;它支持可变长度的标题。我仍然00b,所以欢迎评论:-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()); 

你怎么看;这有效吗?我清理资源正确吗?

 类似资料:
  • 我正在尝试配置一个rsyslog服务器来接收来自docker容器的日志。我目前正在使用以下突击队来运行docker容器: 我使用rfc5424,因为从docker到rsyslog的标准日志格式在冒号字符处中断消息,拆分标记remote:shouldshow并将shouldshow添加到消息中。有关此情况的更多信息,请参见:https://github.com/docker/docker/issue

  • 我有一个需求,我需要将包含可变长度记录的文件转换为固定长度记录。这是一个来自大型机的文件。 因为我不能访问大型机上的文件,所以我需要一个示例可变长度记录文件和一种转换为固定长度记录的方法。 我对这种文件是完全陌生的。但是如果我知道如何将这些可变长度的记录映射到固定长度的记录,我可以用Java编码。 这就是我的字段的位置: 所以我期待这样的输出:

  • 我有一个Netty4.x应用程序,它需要发送和接收ASCII消息,从一个固定长度(10位数,零填充)字段开始,包含以#字符为单位的消息大小。消息如下:

  • 问题内容: 我正在尝试为带有超链接的长句子调整对话框()的高度。 我的代码是.. 如果我没有设置首选大小,那么该对话框将非常长,并且不可读。因此,我想将宽度固定为480。 而且,我要根据文字的长度调整高度。 如果运行此代码,则会看到垂直滚动条。但我不想显示该滚动条并调整对话框的高度。 问题答案: 为了固定宽度并调整高度,我亲自使用了这个技巧:您可以使用setSize固定任意高度和目标宽度,然后使用

  • 我是Netty的新手,需要以自定义方式处理消息。我有以下接口: 现在我从客户端收到一些数据,并希望对其进行处理。我正在实现

  • 我需要生成一个固定长度的文本行: 我现在有的是: 这非常有用,因为生成了一个55个字符的固定长度的字符串。 例如,当可选值为空字符串时,就会出现问题,例如: 在string.format中有空字符串不会给出固定的长度,我仍然需要有30个字符的长度。 任何线索都非常感谢!! 谢谢