Netty-based HTTP/2 transport implementation for gRPC Java providing high-performance network communication
—
Server transport functionality provides comprehensive server creation and configuration for accepting gRPC connections using Netty's HTTP/2 implementation.
import io.grpc.Server;
import io.grpc.netty.NettyServerBuilder;
import io.grpc.ServerCredentials;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.handler.ssl.SslContext;
import java.io.File;
import java.io.InputStream;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;The primary entry point for creating gRPC servers with Netty transport.
public static NettyServerBuilder forPort(int port);
public static NettyServerBuilder forPort(int port, ServerCredentials creds);
public static NettyServerBuilder forAddress(SocketAddress address);
public static NettyServerBuilder forAddress(SocketAddress address, ServerCredentials creds);Parameters:
port - The port number to listen onaddress - A SocketAddress to bind tocreds - Server credentials for authentication/encryptionpublic NettyServerBuilder addListenAddress(SocketAddress listenAddress);Parameters:
listenAddress - Additional socket address to listen on (supports multiple bind addresses)public NettyServerBuilder channelType(Class<? extends ServerChannel> channelType);
public NettyServerBuilder channelFactory(ChannelFactory<? extends ServerChannel> channelFactory);
public <T> NettyServerBuilder withOption(ChannelOption<T> option, T value);
public <T> NettyServerBuilder withChildOption(ChannelOption<T> option, T value);Parameters:
channelType - Netty server channel class (e.g., NioServerSocketChannel.class)option - Channel option for the server channel (accepts connections)value - Value for the channel optionwithOption - Configures the server channel that accepts connectionswithChildOption - Configures individual client connection channelspublic NettyServerBuilder bossEventLoopGroup(EventLoopGroup group);
public NettyServerBuilder workerEventLoopGroup(EventLoopGroup group);Parameters:
group - Custom event loop grouppublic NettyServerBuilder sslContext(SslContext sslContext);
public NettyServerBuilder useTransportSecurity(File certChain, File privateKey);
public NettyServerBuilder useTransportSecurity(InputStream certChain, InputStream privateKey);Parameters:
sslContext - Netty SSL context for TLS connectionscertChain - Certificate chain file or streamprivateKey - Private key file or streampublic NettyServerBuilder maxConcurrentCallsPerConnection(int maxCalls);
public NettyServerBuilder maxConnectionIdle(long maxConnectionIdle, TimeUnit timeUnit);
public NettyServerBuilder maxConnectionAge(long maxConnectionAge, TimeUnit timeUnit);
public NettyServerBuilder maxConnectionAgeGrace(long maxConnectionAgeGrace, TimeUnit timeUnit);Parameters:
maxCalls - Maximum number of concurrent calls per connectionmaxConnectionIdle - Maximum time a connection can be idle before being closedmaxConnectionAge - Maximum age of a connection before server closes itmaxConnectionAgeGrace - Grace period for active calls when closing aged connectionstimeUnit - Time unit for the duration valuespublic NettyServerBuilder initialFlowControlWindow(int initialFlowControlWindow);
public NettyServerBuilder flowControlWindow(int flowControlWindow);
public NettyServerBuilder maxInboundMetadataSize(int bytes);
public NettyServerBuilder maxInboundMetadataSize(int soft, int max);
public NettyServerBuilder maxInboundMessageSize(int bytes);Parameters:
initialFlowControlWindow - Initial HTTP/2 flow control window size in bytesbytes - Maximum size for inbound metadata headersConstants:
public static final int DEFAULT_FLOW_CONTROL_WINDOW = 1048576; // 1 MiBpublic NettyServerBuilder keepAliveTime(long keepAliveTime, TimeUnit timeUnit);
public NettyServerBuilder keepAliveTimeout(long keepAliveTimeout, TimeUnit timeUnit);
public NettyServerBuilder permitKeepAliveTime(long keepAliveTime, TimeUnit timeUnit);
public NettyServerBuilder permitKeepAliveWithoutCalls(boolean permit);Parameters:
keepAliveTime - Time between server-initiated keep-alive pingskeepAliveTimeout - Timeout for keep-alive ping responsespermitKeepAliveTime - Minimum time clients must wait between keep-alive pingspermit - Whether to allow client keep-alive pings when no calls are activepublic NettyServerBuilder maxRstFramesPerWindow(int maxRstStream, int secondsPerWindow);Parameters:
maxRstStream - Maximum number of RST_STREAM frames allowed per time windowsecondsPerWindow - Time window duration in seconds for RST frame countingimport io.grpc.Server;
import io.grpc.netty.NettyServerBuilder;
Server server = NettyServerBuilder.forPort(9090)
.addService(new GreeterImpl())
.build()
.start();
// Keep server running
server.awaitTermination();import io.grpc.netty.NettyServerBuilder;
import java.io.File;
Server server = NettyServerBuilder.forPort(9090)
.useTransportSecurity(
new File("server-cert.pem"),
new File("server-key.pem")
)
.addService(new GreeterImpl())
.maxConcurrentCallsPerConnection(1000)
.maxInboundMetadataSize(8192)
.keepAliveTime(30, TimeUnit.SECONDS)
.keepAliveTimeout(5, TimeUnit.SECONDS)
.permitKeepAliveTime(5, TimeUnit.SECONDS)
.maxConnectionIdle(60, TimeUnit.SECONDS)
.build()
.start();import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(8);
Server server = NettyServerBuilder.forPort(9090)
.channelType(NioServerSocketChannel.class)
.bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup)
.withOption(ChannelOption.SO_BACKLOG, 1024)
.withChildOption(ChannelOption.TCP_NODELAY, true)
.withChildOption(ChannelOption.SO_KEEPALIVE, true)
.addService(new GreeterImpl())
.initialFlowControlWindow(1024 * 1024) // 1MB
.maxConcurrentCallsPerConnection(500)
.build()
.start();import java.net.InetSocketAddress;
Server server = NettyServerBuilder.forPort(9090)
.addListenAddress(new InetSocketAddress("0.0.0.0", 9091))
.addListenAddress(new InetSocketAddress("localhost", 9092))
.addService(new GreeterImpl())
.build()
.start();import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerDomainSocketChannel;
import io.netty.channel.unix.DomainSocketAddress;
EventLoopGroup bossGroup = new EpollEventLoopGroup(1);
EventLoopGroup workerGroup = new EpollEventLoopGroup(4);
Server server = NettyServerBuilder.forAddress(
new DomainSocketAddress("/tmp/grpc.sock"))
.channelType(EpollServerDomainSocketChannel.class)
.bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup)
.addService(new GreeterImpl())
.build()
.start();Server server = NettyServerBuilder.forPort(9090)
.addService(new GreeterImpl())
.maxConcurrentCallsPerConnection(100)
.maxRstFramesPerWindow(10, 10) // Max 10 RST frames per 10 seconds
.permitKeepAliveTime(30, TimeUnit.SECONDS) // Clients must wait 30s between pings
.permitKeepAliveWithoutCalls(false) // No pings without active calls
.build()
.start();Server startup errors are typically thrown as IOException:
try {
Server server = NettyServerBuilder.forPort(9090)
.addService(new GreeterImpl())
.build()
.start();
} catch (IOException e) {
// Handle server startup failure (e.g., port already in use)
System.err.println("Failed to start server: " + e.getMessage());
}Properly shutdown servers to release resources:
Server server = NettyServerBuilder.forPort(9090)
.addService(new GreeterImpl())
.build()
.start();
// Add shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("Shutting down gRPC server...");
server.shutdown();
try {
if (!server.awaitTermination(30, TimeUnit.SECONDS)) {
server.shutdownNow();
}
} catch (InterruptedException e) {
server.shutdownNow();
Thread.currentThread().interrupt();
}
}));
// Wait for termination
server.awaitTermination();When using custom event loop groups, ensure proper shutdown:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(8);
try {
Server server = NettyServerBuilder.forPort(9090)
.bossEventLoopGroup(bossGroup)
.workerEventLoopGroup(workerGroup)
.addService(new GreeterImpl())
.build()
.start();
server.awaitTermination();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}Install with Tessl CLI
npx tessl i tessl/maven-io-grpc--grpc-netty