当前位置:网站首页>Handwritten online chat system (principle part 1)

Handwritten online chat system (principle part 1)

2022-07-06 18:41:00 Java confidant_

Click on the official account , Practical technical articles Know in time 3913958afa69b58c3ce4cf35cab5e107.png

Abstract : Frontier learning Netty Related principles , While implementing an online chat system . This article mainly talks about some Netty The basic principle of 、 technological process , It may be a little boring , But it's also important , relevant demo You'd better type the code yourself , It's easier to understand . But don't worry about being too complicated , This is just the equivalent of Netty Of Hello World.

One 、 catalogue

  • Pre knowledge points

    • NIO

  • Netty Core components

    • Channel

    • Callback

    • Future and Promise

    • Events and ChannelHandler

  • Hello World

Two 、 Pre knowledge points

1、NIO

First, we need to review , Sync 、 asynchronous 、 Blocking 、 Non blocking related concepts .

  • Sync : call API after , Caller can “ immediately ” You know the result of the operation .

  • asynchronous : Relative to synchronization , call API after , The caller cannot “ immediately ” Know the result of the operation , Wait for the callee Callback Inform the result .

  • Blocking : Wait for all data to be read ( write in ) After completion , To return to .

  • Non blocking : When reading , Return as much as you read ; When writing , How much is written and how much is returned . Don't wait for , After all data operations are completed , To return to .

NIO It's a kind of Synchronous nonblocking Of I/O Model .

  • Synchronization means that threads are constantly polling I/O Is the event ready .

  • Nonblocking is when a thread is waiting I/O When , You can do other tasks at the same time .

The core of synchronization is Selectors , The selector replaces the polling of the thread itself I/O event , Avoid blocking and reduce unnecessary thread consumption ; The core of non blocking is Channels and buffers , When I/O When the event is ready , You can write to the buffer , Guarantee I/O The success of the , Without thread blocking waiting .

NIO There are three core parts :

  • Channel( passageway )

  • Buffer( buffer )

  • Selector( Selectors )

Tradition I/O be based on Byte stream and character stream To operate , and NIO be based on Channel and Buffer To operate , Data is always read from the channel into the buffer , Or write from buffer to channel .Selector Used to listen for multiple channel events ( Connection open , Data arrival, etc ). therefore , A single thread can listen to multiple data channels , As shown in the figure below :

86be3d3fb80d02559e8971604e6dc421.png

NIO

3、 ... and 、Netty Core components

1、Channel

Channel It's a passage , Used to connect byte buffers Buffer And the other end of the entity . stay NIO In the network programming model , Server and client I/O Data interaction ( Get information that they push each other ) The medium of Channel.

Netty Yes JDK Native ServerSocketChannel Packaged and enhanced .

Netty Of Channel Add the following components :

  • id Identify unique identity information

  • There may be parent Channel

  • The Conduit pepiline

  • For data reading and writing unsafe Inner class

  • Event loop actuator NioEventLoop

Channel It falls into two categories :

  • Server side : NioServerSocketChannel

  • client : NioSocketChannel

The specific dependencies are shown in the following figure :

Server side : NioServerSocketChannel

e095fd32a7aef552493e7b4e8f488524.pngNioServerSocketChannel

client : NioSocketChannel

95d1092517596c9f3a29485f19e0ca78.png

NioSocketChannel

2、Callback

callback It's a callback , A method can call this back in due course callback Method .callback It is one of the most commonly used methods for notifying interested parties that an operation has been completed .

Netty Used internally when handling events callback. When one callback Be triggered , Events can be ChannelHandler Interface implementation processing .

A simple example is shown below :

public class ConnectHandler extends ChannelInboundHandlerAdapter {
    //  When a new connection is established ,channelActive  Called 
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
           System.out.println(ctx.channel().remoteAddress());
    }
}

 When a new connection is established ,ChannelHandler  Of  callback  Method  channelActive()  Will be called , Then print a message .

This ConnectHandler example ( Equivalent to the callee ) Pass in the form of parameters to create Channel Connected functions ( caller ) in , Then this function creates a new connection , Will come back to call this ConnectHandler Of channelActive Method , This process is called callback .

3、Future and Promise

Future and Promise Originated from functional programming , The purpose is to set the value (Future) It's not how it's calculated (Promise) Separate , This allows for a more flexible calculation , Especially through parallelization .

Future Represents the return value of the target calculation ,Promise Indicates the way of calculation , This model separates the returned results from the calculation logic , The purpose is to make the calculation logic not affect the return result , Thus, a set of asynchronous programming model is abstracted . The bond between them is Callback.

Simply speaking :Future It means a The result of an asynchronous task , For this result, you can add Callback Methods in order to perform tasks Make corresponding actions after successful or failed execution , and Promise The task executor , The task performer passes Promise You can mark the completion or failure of the task .

stay Netty in :

  • Future Interface defined isSuccess(),isCancellable(),cause() Other methods , These methods for judging the asynchronous execution state are read-only .

  • Promise Interface in extends Future That's an increase from setSuccess(),setFailure() Other methods , These methods are writable , namely Promise It's writable Future.

4、 event (event) and ChannelHandler

ChannelHandler

Netty It's an event driven framework , be-all event( event ) It's all by Handler To process .

ChannelHandler Can handle I/O、 Intercept I/O Or will event Pass to ChannelPipeline The next one in Handler To deal with .

ChannelHandler Its structure is very simple , There are only three ways , Namely :

void handlerAdded(ChannelHandlerContext ctx) throws Exception;
void handlerRemoved(ChannelHandlerContext ctx) throws Exception;
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;

event

Netty With subdivided event( event ) To inform us of changes in state or operation . This allows us to be based on event To trigger appropriate behavior . Such behavior may include :

  • logging

  • Data transfer

  • flow control

  • Applied logic

event Classify according to the relationship of input or output data flow . May be triggered by input data or related state changes event Include :

  • Active or inactive connections

  • Reading data

  • user event

  • error event

And output event Is the result of operations that will trigger future behavior , It could be :

  • Open or close the connection to the remote end

  • Write or brush data to a socket

every last event Can be assigned to a user implementation handler Object method .

Hello World

A simple websocket Server side , As shown below :

Server Code :

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;

public class Server {

    public static void main(String[] args) throws InterruptedException {
        //  Used to receive connections from clients 
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        //  Used to process received connections 
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        //  establish  netty  service 
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap.group(bossGroup, workerGroup)
                    //  Set up  NIO  Pattern 
                    .channel(NioServerSocketChannel.class)
                    //  Set up  tcp  buffer 
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    //  Set the sending buffer data size 
                    .childOption(ChannelOption.SO_SNDBUF, 64 * 1024)
                    //  Set the receiving buffer data size 
                    .option(ChannelOption.SO_RCVBUF, 64 * 1024)
                    //  Maintain long connection 
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            // HttpClient codecs 
                            pipeline.addLast(new HttpServerCodec());
                            //  Set the maximum content length 
                            pipeline.addLast(new HttpObjectAggregator(65536));
                            // WebSocket  Data compression extension 
                            pipeline.addLast(new WebSocketServerCompressionHandler());
                            // WebSocket  handshake 、 Control frame processing 
                            pipeline.addLast(new WebSocketServerProtocolHandler("/", null, true));
                            //  Channel initialization , Data transmission to intercept and execute 
                            pipeline.addLast(new ServerHandler());
                        }
                    });
            //  Bind port to start service 
            ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

ServerHandler Code :

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" Channel activation ( Callback )");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //  Only deal with  TextWebSocketFrame
        if (msg instanceof TextWebSocketFrame) {
            String request = ((TextWebSocketFrame) msg).text();
            System.out.println(" Receive a request :" + request);
            ctx.writeAndFlush(new TextWebSocketFrame("PONG"));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" Data read complete ");
    }
}

pom rely on

<dependencies>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.6.Final</version>
    </dependency>
</dependencies>

And then run Server that will do .

Next, let's test whether the program is normal , Here we use an online testing website :http://www.easyswoole.com/wstool.html

Connect to our service , As shown in the figure below :

532935bcdd8411540f1dc7b7659fdd4b.png

Connect websocket

If appear OPENED => 127.0.0.1:8080 A hint of , The connection is successful . Otherwise, please check whether the program is consistent with the sample code .

Then we click the start sending button , If the following prompt appears, it means , The message was sent successfully .

2eff55a75029edd0255286efd8aae3a7.png

Send a message 1

030960d585f4f55762daf3b1dfa6b25b.png

Send a message 2

All right, come here , our Hello World It's done .

recommend

Java Interview questions

Technical involution group , Learn together !!

f8bebfaacd3e0b039558f5753febe0dd.jpeg

PS: Because the official account platform changed the push rules. , If you don't want to miss the content , Remember to click after reading “ Looking at ”, Add one “ Star standard ”, In this way, each new article push will appear in your subscription list for the first time . spot “ Looking at ” Support us !

原网站

版权声明
本文为[Java confidant_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207061046498746.html