netty series: byte or message? This is a problem

brief introduction

UDT gives you two choices, byte stream or message. Which one do you choose? Experience tells us that only primary school students do multiple-choice questions, and we should all!

Definition of type

How are the two types of UDT defined?

Check out com barchart. UDT package, you can find that these two types are defined in the TypeUDT enumeration class.

	STREAM(1),
	DATAGRAM(2), 

One is called STREAM, and its code is 1. One is called DATAGRAM, and its code is 2

According to two different types, we can create different selectorProvider and channelFactory. These two are exactly what is needed to build netty services.

In the tool class NioUdtProvider, netty provides us with six combinations of TypeUDT and KindUDT, ChannelFactory, which are:

For Stream: BYTE_ACCEPTOR,BYTE_CONNECTOR,BYTE_RENDEZVOUS.

And for Message: MESSAGE_ACCEPTOR,MESSAGE_CONNECTOR and MESSAGE_RENDEZVOUS.

Similarly, there are two corresponding selectorproviders:

BYTE_PROVIDER and MESSAGE_PROVIDER.

Build UDT stream server

If you want to build a UDT stream server, you first need to use nioudtprovider BYTE_ Provider to create NioEventLoopGroup:

        final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.BYTE_PROVIDER);
        final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1, connectFactory, NioUdtProvider.BYTE_PROVIDER);

Here, we create two eventloops, acceptLoop and connectLoop.

Next, bind the above two group s in ServerBootstrap and specify channelFactory. Here we need nioudtprovider BYTE_ ACCEPTOR:

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 UDTByteEchoServerHandler());
                        }
                    });

That's it.

Set up UDT message server

The steps of setting up UDT message server are very similar to that of stream, except that nioudtprovider is required MESSAGE_ Provider as selectorProvider:

        final NioEventLoopGroup acceptGroup =
                new NioEventLoopGroup(1, acceptFactory, NioUdtProvider.MESSAGE_PROVIDER);
        final NioEventLoopGroup connectGroup =
                new NioEventLoopGroup(1, connectFactory, NioUdtProvider.MESSAGE_PROVIDER);

Then use nioudtprovider when Binding ServerBootstrap MESSAGE_ Acceptor as channelFactory:

final ServerBootstrap boot = new ServerBootstrap();
            boot.group(acceptGroup, connectGroup)
                    .channelFactory(NioUdtProvider.MESSAGE_ACCEPTOR)
                    .option(ChannelOption.SO_BACKLOG, 10)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<UdtChannel>() {
                        @Override
                        public void initChannel(final UdtChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(
                                    new LoggingHandler(LogLevel.INFO),
                                    new UDTMsgEchoServerHandler());
                        }
                    });

It's also simple.

handler for Stream and Message

Different UDT types require different handler s.

For Stream, its bottom layer is byte, so our message processing is also carried out in the form of byte. We build message in the following way:

private final ByteBuf message;
message = Unpooled.buffer(UDTByteEchoClient.SIZE);
        message.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));

Then use CTX Writeandflush (message) writes it to the channel.

For message, it is actually the encapsulation of ByteBuf format. netty has a corresponding class called UdtMessage:

public final class UdtMessage extends DefaultByteBufHolder

UdtMessage is a ByteBufHolder, so it is actually a ByteBuf encapsulation.

We need to encapsulate ByteBuf into UdtMessage:

private final UdtMessage message;
final ByteBuf byteBuf = Unpooled.buffer(UDTMsgEchoClient.SIZE);
        byteBuf.writeBytes("www.flydean.com".getBytes(StandardCharsets.UTF_8));
        message = new UdtMessage(byteBuf);

Then send the UdtMessage to the channel:

ctx.writeAndFlush(message);

In this way, you will learn to use stream and message data types in UDT protocol.

summary

You may think that the implementation of different data types is so simple. This is all due to netty's excellent packaging and design.

Thanks, netty!

Examples of this article can refer to: learn-netty4

This article has been included in http://www.flydean.com/40-netty-udt-support-2/

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!

Keywords: Java Netty Back-end

Added by jv2222 on Fri, 11 Feb 2022 22:43:04 +0200