brief introduction
We know that the foundation of netty is channel and the selector on channel. Of course, as a nio framework, channel and selector are not only the foundation of netty, but also the foundation of all nio implementations.
Similarly, we know that netty has many different protocols. These protocols communicate on the channel. Will the channel and selector used be different for different protocols?
With this question, let's explore it in depth.
The basic construction method of netty service
Netty can be divided into client-side and server-side. In fact, there is little difference between the construction methods of client-side and server-side. Here, for the sake of simplicity, take the construction of server-side in netty as an example.
Review the netty server we built at the beginning. The corresponding code is as follows:
//Establish two eventloopgroups to handle connections and messages EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new FirstServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); // Bind ports and start receiving connections ChannelFuture f = b.bind(port).sync();
We should pay attention to two places, one is the group method of ServerBootstrap, and the other is its channel method.
EventLoopGroup
group can be implemented in two ways, one parameter or two parameters. The parameters are eventloopgroup. Eventloopgroup is mainly used to register the channel for subsequent selectors to select.
If one parameter is used, an EventLoopGroup will handle both acceptor and client events. If two parameters are used, they will be separated.
Of course, this is not the focus of today's talk. Today's talk is about how the construction of EventLoopGroup is different in different protocols.
EventLoopGroup itself is an interface. It has many implementations, but it is essentially two eventloops: singlethreadeventloop and MultithreadEventLoopGroup
That is to use single thread for EventLoop processing and multi thread for EventLoop processing.
For example, the NioEventLoopGroup we commonly use above is a single threaded EventLoop.
NioEventLoopGroup usually uses a parameterless constructor. In fact, NioEventLoopGroup can pass in threadfactory, the number of threads, SelectorProvider and SelectStrategyFactory
netty provides only one implementation of SelectStrategyFactory: DefaultSelectStrategyFactory.
For SelectorProvider, the default implementation is SelectorProvider Provider (), let's see the specific implementation of this method:
public static SelectorProvider provider() { synchronized (lock) { if (provider != null) return provider; return AccessController.doPrivileged( new PrivilegedAction<SelectorProvider>() { public SelectorProvider run() { if (loadProviderFromProperty()) return provider; if (loadProviderAsService()) return provider; provider = sun.nio.ch.DefaultSelectorProvider.create(); return provider; } }); } }
You can see that by default, SelectorProvider can be created in three ways.
The first is to look up from the system properties: Java nio. channels. spi. SelectorProvider:
String cn = System.getProperty("java.nio.channels.spi.SelectorProvider"); Class<?> c = Class.forName(cn, true, ClassLoader.getSystemClassLoader()); provider = (SelectorProvider)c.newInstance();
If defined, create an instance to return.
If not, the service Loader will be loaded from "META-INF/services /":
private static boolean loadProviderAsService() { ServiceLoader<SelectorProvider> sl = ServiceLoader.load(SelectorProvider.class, ClassLoader.getSystemClassLoader()); Iterator<SelectorProvider> i = sl.iterator();
If the servie is not found, the last default sun. Exe will be used nio. ch.DefaultSelectorProvider.
channel
By default, we use NioServerSocketChannel. It is actually created from the default SelectorProvider mentioned above.
private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider(); return DEFAULT_SELECTOR_PROVIDER.openServerSocketChannel();
Therefore, the channel used should match the selector.
We can use channels directly or channelfactories to generate channels through these factories.
If you want to use channelfactory, you can call the channelfactory method of ServerBootstrap.
Multiple construction methods
The basic netty server construction method is mentioned above. The corresponding is socket protocol.
If UDP connection is required, the corresponding channel should be changed to niodatagram channel, as follows:
EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true) .handler(new UDPServerHandler()); b.bind(PORT).sync().channel().closeFuture().await();
EventLoopGroup can remain unchanged.
Because the bottom layer of netty is based on socket and the bottom layer of socket is based on TCP or UDP protocol, the HTTP or http2 or SOCKS protocols implemented in netty are based on socket connection.
Therefore, for HTTP or http2, channel is still NioServerSocketChannel.
You can see that only the UDP protocol is different. Similarly, the UDT protocol based on UDP protocol is also different, and its use is as follows:
final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER); final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER); final ServerBootstrap boot = new ServerBootstrap(); boot.group(acceptGroup, connectGroup) .channelFactory(NioUdtProvider.BYTE_ACCEPTOR) .option(ChannelOption.SO_BACKLOG, 10) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<UdtChannel>() { @Override public void initChannel(final UdtChannel ch) { ch.pipeline().addLast( new LoggingHandler(LogLevel.INFO), new UDTEchoServerHandler()); } });
UDT uses byte provided in NioUdtProvider_ Provider and BYTE_ACCEPTOR acts as selector and channelFactory respectively.
Other channel s
In addition to NioSocketChannel, there are EpollChannel, KQueueChannel and SctpChannel, which are used for different protocols. We will introduce it in detail in subsequent articles.
summary
channel and selector are the basis of netty. On this basis, netty can extend and adapt to all protocols based on tcp and udp, which can be said to be very powerful.
This article has been included in http://www.flydean.com/39-netty-selecto...r-channelfactory/
The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to find!
Welcome to my official account: "those things in procedure", understand technology, know you better!