public McpeOverRakNetNetworkListener(VoxelwindServer voxelwindServer, String host, int port, boolean useSoReuseport) { this.server = voxelwindServer; this.address = new InetSocketAddress(host, port); this.useSoReuseport = useSoReuseport; if (Epoll.isAvailable()) { bootstrap = new Bootstrap() .channel(EpollDatagramChannel.class) .group(new EpollEventLoopGroup(0, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Voxelwind MCPE Listener - #%d").build())) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) .handler(this); if (useSoReuseport) { bootstrap.option(EpollChannelOption.SO_REUSEPORT, true); } } else { bootstrap = new Bootstrap() .channel(NioDatagramChannel.class) .group(new NioEventLoopGroup(0, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Voxelwind MCPE Listener - #%d").build())) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) .handler(this); } }
/** * Initializes this socket and binds its internal udp socket to a free port. * If the socket is already initialized any invocation of this method will * result in an IllegalStateException. * * @throws SocketException Thrown in case the socket could not be initialized */ public void initialize() throws SocketException { if ( this.isInitialized() ) { throw new IllegalStateException( "Cannot re-initialized ClientSocket" ); } this.udpSocket = new Bootstrap(); this.udpSocket.group( Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup() ); this.udpSocket.channel( Epoll.isAvailable() ? EpollDatagramChannel.class : NioDatagramChannel.class ); this.udpSocket.handler( new ChannelInboundHandlerAdapter() { @Override public void channelRead( ChannelHandlerContext ctx, Object msg ) throws Exception { io.netty.channel.socket.DatagramPacket packet = (io.netty.channel.socket.DatagramPacket) msg; PacketBuffer content = new PacketBuffer( packet.content() ); InetSocketAddress sender = packet.sender(); if ( !receiveDatagram( sender, content ) ) { // Push datagram to update queue: handleDatagram( sender, content, System.currentTimeMillis() ); } } } ); try { this.channel = this.udpSocket.bind( ThreadLocalRandom.current().nextInt( 45000, 65000 ) ).sync().channel(); } catch ( InterruptedException e ) { SocketException exception = new SocketException( "Could not bind to socket" ); exception.initCause( e ); throw exception; } this.afterInitialize(); }
@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); }
public static Class<? extends Channel> getChannelClass() { if (useEpoll) { return EpollDatagramChannel.class; } else { return NioDatagramChannel.class; } }
public static Class<? extends DatagramChannel> getDatagramChannelClass(EventLoopGroup eventLoopGroup) { if (eventLoopGroup instanceof EpollEventLoopGroup) { return EpollDatagramChannel.class; } else { return NioDatagramChannel.class; } }
public void start() throws Exception { if (antenna != null) { throw new Exception("antenna is not null, may have run before"); } logger.info("udp connector port"); this.receiver = new Receiver(); b = new Bootstrap(); b.group(group) .channel(EpollDatagramChannel.class) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) .handler(new ChannelInitializer<EpollDatagramChannel>() { @Override protected void initChannel(EpollDatagramChannel ch) throws Exception { ch.pipeline().addLast( receiver.getClass().getName() + " " + receiver.hashCode(), receiver); ch.pipeline().addLast( UDPWriteHandler.class.getName() + " " + System.currentTimeMillis(), new UDPWriteHandler()); } }); ChannelFuture f = b.bind(port); antenna = f.channel(); this.sender = new Sender(antenna); this.sender.init(); f.sync(); logger.info("udp connector port:{}", port); }
/** * Initializes event loop group. */ private void initEventLoopGroup() { // try to use EpollEventLoopGroup if possible, // if OS does not support native Epoll, fallback to use netty NIO try { eventLoopGroup = new EpollEventLoopGroup(); channelClass = EpollDatagramChannel.class; } catch (NoClassDefFoundError e) { log.debug("Failed to initialize native (epoll) transport. " + "Reason: {}. Proceeding with NIO event group.", e); } eventLoopGroup = new NioEventLoopGroup(); channelClass = NioDatagramChannel.class; }
/** * Binds the server socket to the specified address. This operation initializes this socket. * * @param address The address to bind the port to * * @throws SocketException Thrown if the socket cannot be bound */ public void bind( InetSocketAddress address ) throws SocketException { if ( this.bindAddress != null ) { throw new SocketException( "ServerSocket is already bound" ); } // Automatically binds socket to address (no further #bind() call required) this.udpSocket = new Bootstrap(); this.udpSocket.group( Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup() ); this.udpSocket.channel( Epoll.isAvailable() ? EpollDatagramChannel.class : NioDatagramChannel.class ); this.udpSocket.handler( new ChannelInboundHandlerAdapter() { @Override public void channelRead( ChannelHandlerContext ctx, Object msg) throws Exception { DatagramPacket packet = (DatagramPacket) msg; PacketBuffer content = new PacketBuffer( packet.content() ); InetSocketAddress sender = packet.sender(); if ( !receiveDatagram( sender, content ) ) { // Push datagram to update queue: handleDatagram( sender, content, System.currentTimeMillis() ); } } } ); try { this.channel = this.udpSocket.bind( address ).sync().channel(); } catch ( InterruptedException e ) { SocketException exception = new SocketException( "Could not bind to socket" ); exception.initCause( e ); throw exception; } this.bindAddress = address; this.connectionsByAddress = new ConcurrentHashMap<>( this.maxConnections ); this.connectionsByGuid = new ConcurrentHashMap<>( this.maxConnections ); // Initialize other subsystems; won't get here if bind fails as DatagramSocket's // constructor will throw SocketException: this.afterInitialize(); }
public static Class<? extends Channel> getDatagramChannel() { return epoll ? EpollDatagramChannel.class : NioDatagramChannel.class; }
@Override public Class<? extends DatagramChannel> getDatagramChannel(EventLoopGroup group) { return useEpoll(group) ? EpollDatagramChannel.class : NioDatagramChannel.class; }
@SuppressWarnings("unchecked") protected static <C extends DatagramChannel> Class<C> getDatagramChannelClass(boolean epoll) { return (Class) (epoll ? EpollDatagramChannel.class : NioDatagramChannel.class); }