【Netty4 简单项目实践】十、Http协议下使用protocol buff

来源:互联网 发布:清华大学网络学堂登陆 编辑:程序博客网 时间:2024/06/04 19:35

【前言】接手了一个新项目,要对接一个很大的“结构体”,传输协议是Http,载荷打算用protocol buff封装。为了让结构更轻,继续用了Netty框架,那么现在的问题就是:如何在Netty上基于Http协议来接收protocol buff。本系列第三篇是基于TCP方式使用protocol buff


【发送端】发送端依然使用java,虽然是Http,但是我们直接发送字节数组,关键点在Content-Type的设置。以URLConnection为例

    private String address;    private BufferedWriter writer = null;    private BufferedReader reader = null;    private JSONObject jObject = null;    public HttpPost(String address) {        this.address = address;    }

public String sendBytes(byte[] bytes) {        String line = null;        StringBuilder sb = new StringBuilder();        try {            URL url = new URL(address);            URLConnection conn = url.openConnection();            conn.setUseCaches(false); //不用缓存            //设置超时时间            conn.setConnectTimeout(new Integer(Property.getProperty("connectTimeout")).intValue());            conn.setReadTimeout(new Integer(Property.getProperty("readTimeout")).intValue());            conn.setRequestProperty("accept", "*/*");            conn.setRequestProperty("connection", "Keep-Alive");            conn.setRequestProperty("user-agent", "myServer");            conn.setRequestProperty("Content-Type", "application/octet-stream;charset=utf-8");            conn.setDoOutput(true);            conn.setDoInput(true);            conn.connect();            writer = new BufferedWriter(new PrintWriter(conn.getOutputStream()));            writer.write(new String(bytes));            writer.flush();                        reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));                        while ((line = reader.readLine()) != null) {                sb.append(line);                }        } catch(Exception e) {        } finally {            try{                if(writer!=null){                    writer.close();                }                if(reader!=null){                    reader.close();                }            }            catch(IOException ex){            }        }               return sb.toString();    }

有了HTTP发送端之后,再看下protocol buff获取byte[] 的方法:

比如有一个 MyProtocolBuff 的 对象 buff,用.toByteArray()方法就可以得到buff对象对应的byte[]

调用 sendBytes(buff.toByteArray()); 就能在Http中把buff发出去了。


【接收端】接收端要在处理Http协议的handler中处理代码,比如我实现了一个HTTPHandler

public class HTTPHandler extends SimpleChannelInboundHandler<FullHttpRequest>{        @Override    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {        //消息体        ByteBuf buff = request.content();    }

ByteBuf buff = request.content(); 就得到一个Netty专属ByteBuf(底层buf,当实现了SimpleChannelInboundHandler接口后,在channelRead0方法调用完成后会自动释放,原理是SimpleChannelInboundHandler中的autoRelease标记)。我们拿到ByteBuf后,需要用特别的方式从它内部存储结构中获取byte[]数组:

        int length = buff.writerIndex() - buff.readerIndex();        byte[] bytes = new byte[length]; // 传入的Byte数据        buff.getBytes(buff.readerIndex(), bytes);
最后我们用bytes在接收端恢复MyProtocolBuff对象
MyProtocolBuff receivedBuff = MyProtocolBuff.parseFrom(bytes);

即可。

0 0
原创粉丝点击