All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.rainbow.netty.NettyClient Maven / Gradle / Ivy

The newest version!
package com.github.rainbow.netty;

import com.alibaba.fastjson.JSONObject;
import com.github.rainbow.common.HeartbeatHandler;
import com.github.rainbow.config.RainbowConfig;
import com.github.rainbow.config.RainbowConfigHelper;
import com.github.rainbow.config.RainbowConstants;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * netty客户端
 */
public class NettyClient {

    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);

    protected static final Queue waitQueue = new LinkedList<>();

    private NioEventLoopGroup workGroup = new NioEventLoopGroup(4);
    private Channel channel;
    private Bootstrap bootstrap;

    /** 用来限制start()只执行一次的 */
    private final AtomicBoolean INITIALIZED = new AtomicBoolean(false);

    //region 单例模式,静态内部类实现

    private NettyClient(){
        //为防止通过反射进行实例化操作打破单例
        if(ClientInstance.instance != null){
            throw new RuntimeException("不可以通过反射进行实例化呦~");
        }
    }

    private static class ClientInstance{
        private static final NettyClient instance = new NettyClient();
    }

    public static NettyClient getInstance(){
        NettyClient nettyClient = ClientInstance.instance;
        return nettyClient;
    }

    //endregion 单例

    /**
     * client的核心方法
     * */
    public void start() {
        if (INITIALIZED.compareAndSet(false, true)) {
            bootstrap = new Bootstrap();
            bootstrap
                    .group(workGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(
                                    new IdleStateHandler(0, 0, 25),
                                    new LengthFieldBasedFrameDecoder(0x200000, 0, 4, -4, 0),
                                     new NettyClientHandler(NettyClient.this));
                        }
                    });
            doConnect();
        }
    }


    protected void doConnect() {

        try {
            Long l = waitQueue.poll();
            if(l != null){
                Thread.sleep(l);
            }
        } catch (Exception e) {
            logger.warn("暂停失败,msg:{}",e.getMessage());
        }

        //从~/.configcenter/config-config.cfg文件中获取配置中心的host和port
        String[] split = RainbowConfigHelper.getInstance().getServerAddress().split(":");
        String host = split[0];
        int port = Integer.parseInt(split[1]);
        final JSONObject body = new JSONObject();
        Properties properties = RainbowConfig.getProperties();
        body.put(RainbowConstants.RAINBOW_SERVER_APP,properties.getProperty(RainbowConstants.RAINBOW_APPNAME));
        body.put(RainbowConstants.RAINBOW_SERVER_ENV,properties.getProperty(RainbowConstants.RAINBOW_ENV));
        body.put(RainbowConstants.RAINBOW_SERVER_ROUPSNAME,properties.getProperty(RainbowConstants.RAINBOW_GROUPSNAME));

        if (channel != null && channel.isActive()) {
            return;
        }

        ChannelFuture future = bootstrap.connect(host, port);

        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture futureListener) throws Exception {
                if (futureListener.isSuccess()) {
                    channel = futureListener.channel();

                    ByteBuf buf = channel.alloc().buffer(5 + body.toJSONString().getBytes().length);
                    buf.writeInt(5 + body.toJSONString().getBytes().length);
                    buf.writeByte(HeartbeatHandler.DATA_MSG);
                    buf.writeBytes(body.toJSONString().getBytes());
                    channel.writeAndFlush(buf);

                    logger.debug("Connect to server successfully!");
                } else {
                    logger.debug("Failed to connect to server, try connect after 10s");
                    futureListener.channel().eventLoop().schedule(new Runnable() {
                        @Override
                        public void run() {
                            doConnect();
                        }
                    }, 10, TimeUnit.SECONDS);
                }
            }
        });
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy