首页>代码>Netty基于DTU协议操作字节序之服务端、客户端、websocket客户端源码实现>/springboot-netty-dtu-client/src/main/java/com/example/im/NettyClient.java
package com.example.im;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.example.im.codec.ByteArrayDecoder;
import com.example.im.codec.ByteArrayEncoder;
import com.example.im.handler.ExceptionHandler;
import com.example.im.handler.LoginResponseHandler;
import com.example.instant.ProtoInstant;
import com.example.util.CharacterConvert;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

/**
 * netty客户端连接类
 * @author 关注微信公众号:程就人生,获取更多源码
 * @date 2020年7月29日
 * @Description 
 *
 */
@Component
public class NettyClient {
	
	private static Logger log = LoggerFactory.getLogger(NettyClient.class);
	
    // 服务器ip地址
	@Value("${netty.communication.host}")
    private String host;
    
    // 服务器端口
	@Value("${netty.communication.port}")
    private int port;
    
    private Channel channel;
    
    
    @Autowired
    private LoginResponseHandler loginResponseHandler;
    
    @Autowired
    private ExceptionHandler exceptionHandler;
    
    private Bootstrap bootstrap;
    
    private EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

    @PostConstruct
    public void start() throws Exception {
        //启动客户端
    	doConnect();
    }    
    
    /**
     * 连接操作
     */
    private void doConnect() {
        try {
        	bootstrap = new Bootstrap();

        	bootstrap.group(eventLoopGroup);
        	bootstrap.channel(NioSocketChannel.class);
        	bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        	bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        	bootstrap.remoteAddress(host, port);

            // 设置通道初始化
        	bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                        public void initChannel(SocketChannel ch) {
                        	//编解码处理
                            ch.pipeline().addLast("decoder", new ByteArrayDecoder());
                            ch.pipeline().addLast("encoder", new ByteArrayEncoder());
                       	    //登录返回处理
                            ch.pipeline().addLast("loginHandler", loginResponseHandler);
                            //异常处理
                            ch.pipeline().addLast("exception", exceptionHandler);
                        }
                    }
            );
            log.info("客户端开始连接");
            ChannelFuture f = bootstrap.connect();
            f.addListener(connectedListener);
        } catch (Exception e) {
        	e.printStackTrace();
            log.info("客户端连接失败!" + e.getMessage());
        }
    }
    
    //连接关闭监听
    GenericFutureListener<ChannelFuture> closeListener = (ChannelFuture f) -> {
		log.info(new Date() + ": 连接已经断开……");
		channel = f.channel();
	};

	//连接监听
	GenericFutureListener<ChannelFuture> connectedListener = (ChannelFuture f) -> {
		final EventLoop eventLoop = f.channel().eventLoop();
		if (!f.isSuccess()) {
			log.info("连接失败!在10s之后准备尝试重连!");
			eventLoop.schedule(() -> doConnect(), 10, TimeUnit.SECONDS);
		} else {
			log.info("服务器 连接成功!" + f.channel().remoteAddress() + ":" + f.channel().localAddress());
			channel = f.channel();
			login();
		}
	};
	
	/**
	 * 登录操作
	 */
	private void login(){
		//构建登录请求
		ByteBuf buf = Unpooled.buffer(3);
		//登录
		buf.writeByte(ProtoInstant.LOGIN);
		buf.writeByte(ProtoInstant.DEVICE_ID);
		//校验位
		int sum = CharacterConvert.sum(ProtoInstant.FIELD_HEAD,6,ProtoInstant.LOGIN,ProtoInstant.DEVICE_ID);
		int verify = CharacterConvert.getLow8(sum);
		buf.writeByte(verify);
		writeAndFlush(buf.array());
	}
    
    /**
     * 发送消息
     * @param msg
     */
    public void writeAndFlush(Object msg){
    	this.channel.writeAndFlush(msg).addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future)
                    throws Exception {
                // 回调
                if (future.isSuccess()) {
                	log.info("请求netty服务器,消息发送成功!");
                } else {
                	log.info("请求netty服务器,消息发送失败!");
                }
            }
        });
    }
    
    /**
	 * 重新建立连接
	 * @throws Exception
	 */
	public void reconnect() throws Exception {
        if (channel != null && channel.isActive()) {
            return;
        }
        log.info("reconnect....");
        start();
        log.info("reconnect success");
    }

	/**
	 * 关闭连接
	 */
    public void close() {
    	eventLoopGroup.shutdownGracefully();
    }
}
最近下载更多
shenmofeng11  LV1 2022年12月8日
xiaoche117  LV17 2022年9月15日
mtx147369  LV1 2022年8月10日
xujiaheng  LV2 2022年5月30日
jaonsang  LV25 2022年4月8日
18513928828  LV1 2021年8月9日
崔春晓 2021年7月19日
暂无贡献等级
jacco_su  LV1 2021年4月19日
chltiger  LV3 2021年4月12日
396957748  LV1 2021年3月8日
最近浏览更多
18728748707  LV13 5月9日
流水本无情  LV9 3月13日
内心向阳  LV4 2023年11月8日
zgbi2008  LV1 2023年4月11日
shenmofeng11  LV1 2022年12月8日
wz520135  LV7 2022年10月16日
crosa_Don  LV18 2022年10月7日
xiaoche117  LV17 2022年9月15日
adimgaoshou  LV10 2022年9月6日
mtx147369  LV1 2022年8月10日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友