基于Netty的RPC简单框架实现(四):Netty实现网络传输

1.Netty

Netty是由JBOSS提供的一个java开源框架。在吸收了FTP,SMTP,HTTP,各种二进制,文本协议等多种协议的实现经验,并经过设计相当精心的项目后,Netty最终成功地找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。Netty是一个基于NIO的客户,服务器端编程框架,使用Netty可以确保你快速和简单的开发出一个网络应用。

建议参考《Netty权威指南》或《Netty In Action》,后者已有中文翻译版本在此


2.依赖配置

本例使用netty 4.0.23.Final实现网络通信

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.0.23.Final</version>
    <scope>compile</scope>
</dependency>
使用maven直接在pom.xml中添加上面的依赖即可


3.ChannelHandler设计

本例情景相对简单,在客户端和服务端均只有3个ChannelHandler。两者均有一个NettyKryoEncoder和一个NettyKryoDecoder。其中NettyKryoEncoder用于将发送的对象序列化为字节序列,是一个ChannelInboundHandler。而NettyKryoDecoder用于从接收到的字节序列还原出对象,是一个ChannelOutboundHandler。

客户端还有一个RpcClientDispatchHandler,用于接收到服务端返回的对象时(实际应用场景中只可能为RpcResponse对象)进行事件的分发。与之类似,服务端设有一个RpcServerDispatchHandler,用于接收到客户端发送的对象时(实际应用场景中只可能为RpcRequest对象)进行事件分发。

(1).NettyKryoEncoder

package com.maigo.rpc.netty;

import com.maigo.rpc.serializer.KryoSerializer;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class NettyKryoEncoder extends MessageToByteEncoder<Object>
{	
	@Override
	protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out)
			throws Exception 
	{
		KryoSerializer.serialize(msg, out);
	}
}
直接调用上一节实现的KryoSerializer进行序列化


(2).NettyKryoDecoder

package com.maigo.rpc.netty;

import com.maigo.rpc.serializer.KryoSerializer;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

public class NettyKryoDecoder extends LengthFieldBasedFrameDecoder
{		
	public NettyKryoDecoder() 
    {
        super(1048576, 0, 4, 0, 4);
    }
	
	@Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception 
    {
        ByteBuf frame = (ByteBuf) super.decode(ctx, in);
        if (frame == null) 
            return null;
                
        return KryoSerializer.deserialize(frame);
    }

    @Override
    protected ByteBuf extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length) 
    {
        return buffer.slice(index, length);
    }
}
使用LengthFieldBasedFrameDecoder进行解码,解码依赖于字节序列的头部的4个字节中存放的长度信息(KryoSerializer.serialize()方法会在头部写入长度信息,详见上一节)。获取到长度信息后使用父类的decode()方法截取出实际的字节序列,直接调用KryoSerializer的deserialize()方法反序列化还原出对象。


(3).RpcClientDispatchHandler

package com.maigo.rpc.client;

import com.maigo.rpc.context.RpcResponse;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class RpcClientDispatchHandler extends ChannelInboundHandlerAdapter
{
	private RpcClientResponseHandler rpcClientResponseHandler;
	private RpcClientChannelInactiveListener rpcClientChannelInactiveListener = null;
	
	public RpcClientDispatchHandler(
			RpcClientResponseHandler rpcClientResponseHandler, 
			RpcClientChannelInactiveListener rpcClientChannelInactiveListener) 
	{
		this.rpcClientResponseHandler = rpcClientResponseHandler;
		this.rpcClientChannelInactiveListener = rpcClientChannelInactiveListener;
	}

	@Override
	public void channelRead(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值