Channel是通道,那么pipeline就是通道里面的管道,具体的解释能够参考:http://ifeve.com/channel-pipeline/,咱们在管道里加入消息的编码和解码器:java
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("HBeat", new IdleStateHandler( ConstantManager.HEART_BEAT + 10, ConstantManager.HEART_BEAT, 0));// 心跳 pipeline.addLast("MsgDecoder", new ProtobufDecoder());// 解码器 pipeline.addLast("MsgEncoder", new ProtobufEncoder());// 编码器 pipeline.addLast("handler", new AppServerHandler());// 消息处理器 } });
1. ProtobufEncoder()方法对消息进行编码,具体实现以下:bootstrap
public class ProtobufEncoder extends MessageToByteEncoder<Message> { /** * 日志对象 */ private final Logger Log = LoggerFactory.getLogger(getClass()); @Override protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception { byte[] bytes = msg.toByteArray();// 将对象转换为byte // 加密消息体 ThreeDES des = ctx.channel().attr(AppAttrKeys.ENCRYPT).get(); byte[] encryptByte = des.encrypt(bytes); int length = encryptByte.length;// 读取消息的长度 ByteBuf buf = Unpooled.buffer(2 + length); buf.writeShort(length);// 先将消息长度写入,也就是消息头 buf.writeBytes(encryptByte);// 消息体中包含咱们要发送的数据 out.writeBytes(buf); Log.info("[APP-SERVER][SEND][remoteAddress:" + ctx.channel().remoteAddress() + "][total length:" + length + "][bare length:" + msg.getSerializedSize() + "]:\r\n" + msg.toString()); } }
1. 必需要写覆盖父类的方法encode,在其中对消息进行DES加密,des.encrypt(bytes)ide
下面是加密方法:编码
public byte[] encrypt(byte[] plainByte) { byte[] cipherByte = null; try { DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory .getInstance("DESede"); SecretKey securekey = keyFactory.generateSecret(dks); Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, securekey); cipherByte = cipher.doFinal(plainByte); } catch (Exception e) { Log.error(e.getMessage(), e); } return cipherByte; }