Netty Client的简单封装
Netty 基于java NIO 网络通信框架,具有高效、简单、快速的应用特点。
Netty Client
NettyClient
NettyClientManager
public class NettyClient {
public static final int Port = 8888;
public static final String IP = "192.168.0.100";
private NioEventLoopGroup groupConnected = null;
private Bootstrap bootstrap;
private static NettyClient client;
private Channel channel;
//连接线程
private Thread mThread;
private ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
private boolean isUseThread = true;
//发送数据句柄
public ChannelHandlerContext connectHanlerCtx;
//回调接口
private IConnectedReadDataListener connectedReadDataListener;
public static NettyClient getInstance(){
return client;
}
public static void initNettyClient(IConnectedReadDataListener listener){
if(client == null) {
client = new NettyClient(listener);
}
}
private NettyClient(IConnectedReadDataListener listener){
connectedReadDataListener = listener;
initNettyClient();
}
/**
* 连接服务
*/
public void starConnect(final int port, final String ip){
if(isUseThread){
startByThread(port,ip);
}else{
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
startNettyclient(port,ip);
}
});
}
}
private void startByThread(final int port, final String ip){
try {
if(mThread != null) {
mThread.interrupt();
}
mThread = new Thread(new Runnable() {
@Override
public void run() {
startNettyclient(port, ip);
}
});
mThread.start();
}catch (Exception e){
e.printStackTrace();
}
}
private void initNettyClient(){
groupConnected = new NioEventLoopGroup();
bootstrap = new Bootstrap();
// 指定channel类型
bootstrap.channel(NioSocketChannel.class);
// 指定Handler
bootstrap.handler(connectedChannelInitializer);
bootstrap.option(ChannelOption.SO_KEEPALIVE,true);
// 指定EventLoopGroup
bootstrap.group(groupConnected);
}
private void startNettyclient(final int port, final String ip){
try {
ChannelFuture cf = bootstrap.connect(new InetSocketAddress(ip, port));
cf.addListener(new ChannelFutureListener(){
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (!channelFuture.isSuccess()) {
final EventLoop loop = channelFuture.channel().eventLoop();
loop.schedule(new Runnable() {
@Override
public void run() {
//start();
}
}, 1L, TimeUnit.SECONDS);
} else {
channel = channelFuture.channel();
}
}
});
channel = cf.sync().channel();
channel.closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
/**
* 连接工具
*/
private ChannelInitializer connectedChannelInitializer = new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyChannelHandle());
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,4,4,-8,0));
}
};
@ChannelHandler.Sharable
public class NettyChannelHandle extends ChannelInboundHandlerAdapter{
private ByteBuf dataBuf;
@Override
public void channelRegistered(ChannelHandlerContext channelHandlerContext) throws Exception {
connectHanlerCtx = channelHandlerContext;
}
@Override
public void channelUnregistered(ChannelHandlerContext channelHandlerContext) throws Exception {
connectHanlerCtx = null;
}
@Override
public void channelActive(ChannelHandlerContext channelHandlerContext) throws Exception {
LogUtils.e("channelActive" );
connectHanlerCtx = channelHandlerContext;
if(connectedReadDataListener != null){
connectedReadDataListener.onConnectedState(true);
}
}
@Override
public void channelInactive(ChannelHandlerContext channelHandlerContext) throws Exception {
LogUtils.e("channelInactive" );
LogUtils.i(" no connect client netty ");
connectHanlerCtx = null;
if(connectedReadDataListener != null){
connectedReadDataListener.onConnectedState(false);
}
}
@Override
public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
LogUtils.e("channelRead ");
try {
ByteBuf buf = ((ByteBuf) o);
if (dataBuf == null) {
dataBuf = buf;
} else {
dataBuf.writeBytes(buf.array());
}
connectHanlerCtx = channelHandlerContext;
connectHanlerCtx.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void channelReadComplete(ChannelHandlerContext channelHandlerContext) throws Exception {
LogUtils.e("channelReadComplete ");
connectHanlerCtx = channelHandlerContext;
if (connectedReadDataListener != null && dataBuf != null) {
ByteBufInputStream inputStream = new ByteBufInputStream(dataBuf);
connectedReadDataListener.onReceiveData(inputStream);
dataBuf = null;
}
connectHanlerCtx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
if(connectedReadDataListener != null){
connectedReadDataListener.onException(ctx);
}
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext channelHandlerContext) throws Exception {
}
@Override
public void handlerAdded(ChannelHandlerContext channelHandlerContext) throws Exception {
}
@Override
public void handlerRemoved(ChannelHandlerContext channelHandlerContext) throws Exception {
}
}
public ChannelHandlerContext getConnectHanlerCtx() {
return connectHanlerCtx;
}
/**
* 断开连接
*/
public void stopConnected(){
try {
if(channel != null){
try {
channel.close().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}catch (Exception e){
LogUtils.i("error value ="+e.getMessage().toString());
e.printStackTrace();
}
}
public void free(){
try{
if(groupConnected != null){
groupConnected.shutdownGracefully();
}
client = null;
}catch (Exception e){
e.printStackTrace();
}
}
public interface IConnectedReadDataListener{
void onReceiveData(ByteBufInputStream data);
void onConnectedState(boolean state);
void onException(ChannelHandlerContext ctx);
}
}
public class NettyClientManager implements NettyClient.IConnectedReadDataListener {
//private NettyClient mNettyClent;
private INettyListener iNettyListener;
private Thread mReconnectedThread;
private boolean isConnected = false;
private String ip;
private int port;
public NettyClientManager(INettyListener listener) {
iNettyListener = listener;
}
public void startConnect(int port, String ip) {
NettyClient.initNettyClient(this);
this.ip = ip;
this.port = port;
NettyClient.getInstance().starConnect(port, ip);
}
@Override
public void onReceiveData(ByteBufInputStream inputStream) {
if (iNettyListener != null) {
iNettyListener.onReceiveData(inputStream);
}
}
@Override
public void onConnectedState(boolean state) {
isConnected = state;
if (iNettyListener != null) {
if (state) {
iNettyListener.onConnected();
} else {
iNettyListener.onDisconnected();
}
}
}
@Override
public void onException(ChannelHandlerContext ctx) {
try{
if (iNettyListener != null) {
iNettyListener.onException(ctx);
}
}catch (Exception e){
e.printStackTrace();
}
}
public void startReconnected(final int port, final String ip) {
ExecutorService executorService = ThreadUtils.getCachedPool();
executorService.execute(new Runnable() {
@Override
public void run() {
startConnect(port, ip);
}
});
}
private void stopReconnected() {
try {
isConnected = true;
if (mReconnectedThread != null && mReconnectedThread.isAlive()) {
mReconnectedThread.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mReconnectedThread = null;
}
}
public void sendData(PhoneCmd cmd) {
try {
if (NettyClient.getInstance() != null && NettyClient.getInstance().getConnectHanlerCtx() != null) {
ByteBuf buff = NettyClient.getInstance().getConnectHanlerCtx().alloc().buffer(36);
ByteBufOutputStream stream = new ByteBufOutputStream(buff);
stream.write(PrototocalTools.HEAD); // 添加协议头
stream.writeInt(cmd.getProtoId());
Message msg = cmd.getMessage().toBuilder().build();
ByteBuf dataBuff = NettyClient.getInstance().getConnectHanlerCtx().alloc().buffer();
ByteBufOutputStream dataStream = new ByteBufOutputStream(dataBuff);
msg.writeDelimitedTo(dataStream);
dataStream.flush();
int len = dataBuff.capacity();
stream.writeInt(len);
stream.write(dataBuff.array(), 0, len);
stream.flush();
NettyClient.getInstance().getConnectHanlerCtx().writeAndFlush(buff);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 释放资源
*/
public void stop() {
if (NettyClient.getInstance() != null) {
NettyClient.getInstance().stopConnected();
}
if(mReconnectedThread != null && mReconnectedThread.isAlive()){
mReconnectedThread.interrupt();
}
mReconnectedThread = null;
}
public void free(){
stop();
if (NettyClient.getInstance() != null) {
NettyClient.getInstance().free();
}
}
/**
* 是否连接
*
* @return
*/
public boolean isConnected() {
return isConnected;
}
/**
* 接口回调
*/
public interface INettyListener {
void onReceiveData(ByteBufInputStream inputStream);
void onConnected();
void onDisconnected();
void onException(ChannelHandlerContext ctx);
}
}
总结
项目中如果使用netty 客户端的实现 可以参考