com.mpush.netty.udp.NettyUDPConnector.java Source code

Java tutorial

Introduction

Here is the source code for com.mpush.netty.udp.NettyUDPConnector.java

Source

/*
 * (C) Copyright 2015-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     ohun@live.cn ()
 */

package com.mpush.netty.udp;

import com.mpush.api.service.BaseService;
import com.mpush.api.service.Listener;
import com.mpush.api.service.Server;
import com.mpush.api.service.ServiceException;
import com.mpush.tools.thread.ThreadNames;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollDatagramChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.netty.channel.socket.InternetProtocolFamily.IPv4;

/**
 * Created by ohun on 16/10/20.
 *
 * @author ohun@live.cn ()
 */
public abstract class NettyUDPConnector extends BaseService implements Server {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    protected final int port;
    private EventLoopGroup eventLoopGroup;

    public NettyUDPConnector(int port) {
        this.port = port;
    }

    @Override
    protected void doStart(Listener listener) throws Throwable {
        createNioServer(listener);
    }

    @Override
    protected void doStop(Listener listener) throws Throwable {
        logger.info("try shutdown {}...", this.getClass().getSimpleName());
        if (eventLoopGroup != null)
            eventLoopGroup.shutdownGracefully().syncUninterruptibly();
        logger.info("{} shutdown success.", this.getClass().getSimpleName());
        listener.onSuccess(port);
    }

    private void createServer(Listener listener, EventLoopGroup eventLoopGroup,
            ChannelFactory<? extends DatagramChannel> channelFactory) {
        this.eventLoopGroup = eventLoopGroup;
        try {
            Bootstrap b = new Bootstrap();
            b.group(eventLoopGroup)//?Channel,?ipv6,ipv4?
                    .channelFactory(channelFactory).option(ChannelOption.SO_BROADCAST, true)
                    .handler(getChannelHandler());

            initOptions(b);

            //???host???
            b.bind(port).addListener(future -> {
                if (future.isSuccess()) {
                    logger.info("udp server start success on:{}", port);
                    if (listener != null)
                        listener.onSuccess(port);
                } else {
                    logger.error("udp server start failure on:{}", port, future.cause());
                    if (listener != null)
                        listener.onFailure(future.cause());
                }
            });
        } catch (Exception e) {
            logger.error("udp server start exception", e);
            if (listener != null)
                listener.onFailure(e);
            throw new ServiceException("udp server start exception, port=" + port, e);
        }
    }

    private void createNioServer(Listener listener) {
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(1,
                new DefaultThreadFactory(ThreadNames.T_GATEWAY_WORKER));
        eventLoopGroup.setIoRatio(100);
        createServer(listener, eventLoopGroup, () -> new NioDatagramChannel(IPv4));//?Channel,?ipv6,ipv4?
    }

    @SuppressWarnings("unused")
    private void createEpollServer(Listener listener) {
        EpollEventLoopGroup eventLoopGroup = new EpollEventLoopGroup(1,
                new DefaultThreadFactory(ThreadNames.T_GATEWAY_WORKER));
        eventLoopGroup.setIoRatio(100);
        createServer(listener, eventLoopGroup, EpollDatagramChannel::new);
    }

    protected void initOptions(Bootstrap b) {
        b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        b.option(ChannelOption.SO_REUSEADDR, true);
    }

    public abstract ChannelHandler getChannelHandler();

}