【Netty学习】Netty 4.0.x版本和Flex 4.6配合
笔者的男装网店:http://shop101289731.taobao.com 。冬装,在寒冷的冬季温暖你。新品上市,环境选购
=================================不华丽的分割线===============================
因为公司使用的是Netty框架。所以也就去学习了一下。貌似Netty虽然是一个蛮不错的开源框架。但是国内的文档貌似都不是很多。绝大部分都是3.x版本的资料。二最新的版本是4.0.11final(我目前使用的版本)
Netty本身在4.x版本的时候大量连续的版本更新,终于趋于稳定。在4.0.10开始final。也决定好好的写点东西。顺便当做学习笔记来写来自己的学习过程。
Netty4.x相比于3做了很大的改动。大量的改动导致以前的代码不兼容。所以在国内来说。资源资料的匮乏直接导致了我学习相当的艰难。作为一个英语并不好的程序员来说。硬着头皮去看英文指南。文档。和相关的开源项目。
4.x版本的更新说明(官方原版):http://netty.io/wiki/new-and-noteworthy.html
中文翻译版(源自:开源中国的文章):http://www.oschina.net/translate/netty-4-0-new-and-noteworthy
这个翻译版比较古老啦。翻译的一部分内容。我也不是特别认同。推荐大家看英文原版。
改动什么的我就不自己记录了。
官方的文档提供了相对应的文档。API,示例及用户引导。资料目前来讲都是比较旧的。不知道是不是作者没什么时间更新吧。但是大致的思想已经改了。都是属于4.x版本的更新。
--------------------------不华丽的分割线---------------------------
正式内容:
我自己写了一个比较简单的小东西。来辅助自己实现Netty和Flex配合实现Socket通信。当然。代码还在逐步的完善。希望自己能够早点写好他
先讲一下使用到的jar包
两个Flex....包是必须的。有需要的可以自己去BlazeDS查看
先来一个AMF3转换工具类。
这个东西是网上看的代码。转换其实没什么差别的。原理都是一样的原理
1 package com.engine.util; 2 3 import flex.messaging.io.SerializationContext; 4 import flex.messaging.io.amf.Amf3Input; 5 import flex.messaging.io.amf.Amf3Output; 6 import io.netty.buffer.ByteBuf; 7 import io.netty.buffer.Unpooled; 8 9 import java.io.ByteArrayInputStream; 10 import java.io.ByteArrayOutputStream; 11 import java.io.IOException; 12 13 import org.slf4j.Logger; 14 import org.slf4j.LoggerFactory; 15 16 public class AMF3Utils { 17 18 private static final Logger LOG = LoggerFactory.getLogger(AMF3Utils.class); 19 20 /** 21 * Java Object 转换为 AMF3 22 * @param msg 23 * @return 24 * @throws Exception 25 */ 26 public static ByteBuf getAMF3FromObject(Object msg) throws Exception { 27 if(msg == null){ 28 return null; 29 } 30 // Create and instance of the byte array output stream to write the AMF3 31 // object to. 32 final ByteArrayOutputStream bout = new ByteArrayOutputStream(); 33 // Create the AMF3Output object and set its output stream. 34 final Amf3Output amf3Output = new Amf3Output(SerializationContext.getSerializationContext()); 35 amf3Output.setOutputStream(bout); 36 // Write the AMF3 object to the byte array output stream after 37 // converting the source java object. 38 amf3Output.writeObject(msg); 39 // Flush and close the stream. 40 amf3Output.flush(); 41 amf3Output.close(); 42 43 return Unpooled.wrappedBuffer(bout.toByteArray()); 44 } 45 46 /** 47 * AMF3 转换为 Java Object 48 * @param byteBuf 49 * @return 50 * @throws Exception 51 */ 52 public static Object getObjectFromAMF3(ByteBuf byteBuf) throws Exception { 53 ByteArrayInputStream bis = new ByteArrayInputStream(byteBuf.readBytes(byteBuf.readableBytes()).array()); 54 return getObjectFromAMF3(bis); 55 } 56 57 /** 58 * AMF3 转换为 Java Object 59 * @param inputStream 60 * @return 61 * @throws Exception 62 */ 63 public static Object getObjectFromAMF3(ByteArrayInputStream bis) throws Exception { 64 Object obj = null; 65 final Amf3Input amf3Input = new Amf3Input(SerializationContext.getSerializationContext()); 66 try { 67 amf3Input.setInputStream(bis); 68 // Read object does the actual work of conversion. 69 obj = amf3Input.readObject(); 70 // Close the stream 71 amf3Input.close(); 72 } catch (ClassNotFoundException e) { 73 LOG.error("Error in AMF3Utils: {}.\n " + "Check if flash class has corresponding java class.", e); 74 throw e; 75 } catch (IOException e) { 76 LOG.error("IO error in AMF3Utils: {}.", e); 77 throw e; 78 } 79 return obj; 80 } 81 }
Netty解码
1 package com.engine.netty.server.handler.codec; 2 3 import io.netty.buffer.ByteBuf; 4 import io.netty.channel.ChannelHandlerContext; 5 import io.netty.handler.codec.MessageToMessageDecoder; 6 7 import java.io.ByteArrayInputStream; 8 import java.io.IOException; 9 import java.util.List; 10 11 import org.slf4j.Logger; 12 import org.slf4j.LoggerFactory; 13 14 import com.engine.util.AMF3Utils; 15 16 public class DecoderAMF3 extends MessageToMessageDecoder<Object> { 17 18 private static final Logger LOG = LoggerFactory.getLogger(DecoderAMF3.class); 19 20 @Override 21 protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception { 22 if (msg == null) { 23 LOG.warn("Incoming message is null."); 24 return; 25 } 26 try { 27 ByteBuf byteBuf = (ByteBuf) msg; 28 ByteArrayInputStream bis = new ByteArrayInputStream(byteBuf.readBytes(byteBuf.readableBytes()).array()); 29 30 Object obj = AMF3Utils.getObjectFromAMF3(bis); 31 out.add(obj); 32 } catch (IOException e) { 33 LOG.error("IO Error: {}.", e); 34 throw e; 35 } 36 } 37 }
Netty编码
1 package com.engine.netty.server.handler.codec; 2 3 import io.netty.buffer.ByteBuf; 4 import io.netty.channel.ChannelHandlerContext; 5 import io.netty.handler.codec.MessageToMessageEncoder; 6 7 import java.io.IOException; 8 import java.util.List; 9 10 import org.slf4j.Logger; 11 import org.slf4j.LoggerFactory; 12 13 import com.engine.util.AMF3Utils; 14 15 public class EncoderAMF3 extends MessageToMessageEncoder<Object> { 16 17 private static final Logger LOG = LoggerFactory.getLogger(EncoderAMF3.class); 18 19 @Override 20 protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception { 21 try { 22 ByteBuf byteBuf = AMF3Utils.getAMF3FromObject(msg); 23 out.add(byteBuf); 24 } catch (IOException e) { 25 LOG.error("IO Error: {}.", e); 26 throw e; 27 } 28 } 29 }
目前为止这么写。基本上flex的socket通信就可以正常的转换接受和发送的数据了。但是还需要解决发包格式等问题。以避免很多问题。这个我自己在写这篇文章的时候还未解决。准备今天花点时间解决这个小问题。O(∩_∩)O哈哈~
【推荐文章】AMF协议简介: http://yunzhongxia.iteye.com/blog/663747