Introduction to the

Albert Einstein said: All greatness comes from simple details. Netty gives us such a powerful eventLoop, channel and by taking advantage of these simple things, you can get really powerful applications, like proxies.

Proxy and reverse proxy

I believe that as long as programmers should have heard of the Nginx server, this super excellent Nginx is a very important function is to do reverse proxy. If there is a reverse proxy, there must be a forward proxy. What is the difference between the two?

First talk about the positive agent, for example, the flow of stars recently hit, although suppressed, but the star is a star, ordinary people can not see, if someone needs to talk to the star, need to first through the star’s agent, a broker will be conveyed to the star. This broker is a forward agent. We access the object to be accessed through a forward proxy.

So what is a reverse proxy? For example, now there are A lot of artificial intelligence, if we have A conversation with intelligent robot A, and then A transfers the conversation between us to the hidden person behind, this person uses his wisdom to answer our conversation, by intelligent robot A output, finally realize artificial intelligence. This process is called reverse proxy.

Netty implements the principle of proxy

So how to implement this proxy server in Netty?

First of all, the proxy server is a server, so we need to create a server in Netty using ServerBootstrap:

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new SimpleDumpProxyInitializer(REMOTE_HOST, REMOTE_PORT))
             .childOption(ChannelOption.AUTO_READ, false)
             .bind(LOCAL_PORT).sync().channel().closeFuture().sync();
Copy the code

In this local server, we pass in the ProxyInitializer. In this handler initializer, we pass in our custom handler:

    public void initChannel(SocketChannel ch) {
        ch.pipeline().addLast(
                new LoggingHandler(LogLevel.INFO),
                new SimpleDumpProxyInboundHandler(remoteHost, remotePort));
    }
Copy the code

In our custom handler, we use Bootstrap to create a client that connects to the remote proxy server. We place this client creation in the channelActive method:

// enable outbound connection Bootstrap b = new Bootstrap(); b.group(inboundChannel.eventLoop()) .channel(ctx.channel().getClass()) .handler(new SimpleDumpProxyOutboundHandler(inboundChannel)) .option(ChannelOption.AUTO_READ, false); ChannelFuture f = b.connect(remoteHost, remotePort);Copy the code

After the client establishes the connection, it can read data from the inboundChannel:

outboundChannel = f.channel(); F.addlistener (future -> {if (future.issuccess ()) {// If (future.issuccess ()) {inboundchannel.read (); } else {// Close inbound channel inboundchannel.close (); }});Copy the code

Since it is a proxy service, we need to forward the data read by inboundChannel to outboundChannel. Therefore, in channelRead, we need to write:

Public void channelRead(final ChannelHandlerContext CTX, Object MSG) { And write to outboundChannel if (outboundChannel.isActive()) { OutboundChannel. WriteAndFlush (MSG). AddListener ((ChannelFutureListener) future - > {the if (future) isSuccess ()) {/ / flush of success, Read the next message ctx.channel().read(); } else { future.channel().close(); }}); }}Copy the code

After the outboundChannel is written successfully, the inboundChannel is read again.

There is also a handler for the client’s outboundChannel. In this handler, we need to write the data read by the outboundChannel back to the inboundChannel:

Public void channelRead(final ChannelHandlerContext CTX, Object MSG) { And write to the inboundChannel inboundChannel. WriteAndFlush (MSG). The addListener ((ChannelFutureListener) future - > {the if (future.isSuccess()) { ctx.channel().read(); } else { future.channel().close(); }}); }Copy the code

After the inboundChannel writes successfully, the outboundChannel reads again.

So a simple proxy server is done.

In actual combat

What happens if we proxy port 8000 locally to port 80 at www.163.com? Run our program, visit http://localhost:8000, and we’ll see the following page:

Why isn’t the normal page displayed as we expected? That is because the domain name after our proxy is localhost, instead of the normal www.163.com, so the server does not recognize our request, so an error was reported.

conclusion

Simple forwarding requests between proxy servers in this article cannot handle the above scenario, so how to solve the above problem? Stay tuned for my next post!

Learn -netty4 for an example of this article

This article is available at www.flydean.com/35-netty-si…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!