当前位置:网站首页>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
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 :
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
NioServerSocketChannel
client : 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 :
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 .
All right, come here , our Hello World It's done .
recommend
Technical involution group , Learn together !!
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 !
边栏推荐
- There is a sound prompt when inserting a USB flash disk under win10 system, but the drive letter is not displayed
- The role of applet in industrial Internet
- Markdown syntax for document editing (typera)
- Medical image segmentation
- Penetration test information collection - WAF identification
- Test 1234
- Five data structures of redis
- A method of sequentially loading Unity Resources
- SQL injection - access injection, access offset injection
- 徐翔妻子应莹回应“股评”:自己写的!
猜你喜欢
测试行业的小伙伴,有问题可以找我哈。菜鸟一枚~
MySQL查询请求的执行过程——底层原理
From 2022 to 2024, the list of cifar azrieli global scholars was announced, and 18 young scholars joined 6 research projects
Tree-LSTM的一些理解以及DGL代码实现
Shangsilicon Valley JUC high concurrency programming learning notes (3) multi thread lock
Use cpolar to build a business website (1)
CSRF漏洞分析
Maixll-Dock 摄像头使用
[the 300th weekly match of leetcode]
关于npm install 报错问题 error 1
随机推荐
Splay
关于npm install 报错问题 error 1
Stm32+hc05 serial port Bluetooth design simple Bluetooth speaker
Five data structures of redis
C语言自动预订飞机票问题
巨杉数据库首批入选金融信创解决方案!
Maixll dock camera usage
bonecp使用数据源
[the 300th weekly match of leetcode]
Docker installation redis
atcoder它A Mountaineer
Coco2017 dataset usage (brief introduction)
Hongke shares | plate by plate ar application in Beijing Winter Olympics
AcWing 3537.树查找 完全二叉树
华为0基金会——图片整理
AvL树的实现
UDP protocol: simple because of good nature, it is inevitable to encounter "city can play"
Penetration test information collection - basic enterprise information
MySQL查询请求的执行过程——底层原理
STM32+ENC28J60+UIP协议栈实现WEB服务器示例