您好,登錄后才能下訂單哦!
這篇文章主要講解了“Netty中怎么實現前端發送消息,后端接收消息并返回”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Netty中怎么實現前端發送消息,后端接收消息并返回”吧!
今天通過一個故事來講解netty,主要講client和server端和下面的主要實現類。
客戶要去ktv唱歌,進入ktv之前,門口會有招待服務生,然后招待服務生看到客戶之后,會安排你們給ktv內部服務生給你們安排房間,然后帶你們進入ktv房間唱歌,準備開始唱歌就要打開音樂,選好歌曲,打開燈光等因素,之后這個期間你們可能會讓唱歌的服務生來助唱,讓會跳舞的服務生給你們跳舞,甚至讓服務生帶來酒或者吃的,直到你們唱歌結束付完錢離開為止,整個過程就算結束。
專有名詞解釋:
client端:客戶
server端:ktv
mainGroup或者boosGroup:主線程組,相當于ktv門口外的招待服務生
subGroup或者workerGroup:子線程組,相當于ktv內部服務生,負責安排房間的,由招待服務生通知內部服務生安排給他們的
ServerBootstrap :客戶進入ktv之前到離開ktv之后的整個流程
HelloServerInitializer:進入ktv房間之后的整個流程
CustomHandler :分別代表唱歌服務生、端茶送水服務生、跳舞服務生各個實現的功能等等
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * @Description: 實現客戶端發送一個請求,服務器會返回 hello netty */ public class HelloServer { public static void main(String[] args) throws Exception { // 定義一對線程組 // 主線程組, 用于接受客戶端的連接,但是不做任何處理,跟老板一樣,不做事 EventLoopGroup bossGroup = new NioEventLoopGroup(); // 從線程組, 老板線程組會把任務丟給他,讓手下線程組去做任務 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { // netty服務器的創建, ServerBootstrap 是一個啟動類 ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) // 設置主從線程組 .channel(NioServerSocketChannel.class) // 設置nio的雙向通道 .childHandler(new HelloServerInitializer()); // 子處理器,用于處理workerGroup // 啟動server,并且設置8088為啟動的端口號,同時啟動方式為同步 ChannelFuture channelFuture = serverBootstrap.bind(8088).sync(); // 監聽關閉的channel,設置位同步方式 channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpServerCodec; /** * @Description: 初始化器,channel注冊后,會執行里面的相應的初始化方法 */ public class HelloServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel channel) throws Exception { // 通過SocketChannel去獲得對應的管道 ChannelPipeline pipeline = channel.pipeline(); // 通過管道,添加handler // HttpServerCodec是由netty自己提供的助手類,可以理解為攔截器 // 當請求到服務端,我們需要做解碼,響應到客戶端做編碼 pipeline.addLast("HttpServerCodec", new HttpServerCodec()); // 添加自定義的助手類,返回 "hello netty~" pipeline.addLast("customHandler", new CustomHandler()); } }
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpObject; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.util.CharsetUtil; /** * @Description: 創建自定義助手類 */ // SimpleChannelInboundHandler: 對于請求來講,其實相當于[入站,入境] public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { // 獲取channel Channel channel = ctx.channel(); if (msg instanceof HttpRequest) { // 顯示客戶端的遠程地址 System.out.println(channel.remoteAddress()); // 定義發送的數據消息 ByteBuf content = Unpooled.copiedBuffer("Hello netty~", CharsetUtil.UTF_8); // 構建一個http response FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content); // 為響應增加數據類型和長度 response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes()); // 把響應刷到客戶端 ctx.writeAndFlush(response); } } @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { System.out.println("channel。。。注冊"); super.channelRegistered(ctx); } @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { System.out.println("channel。。。移除"); super.channelUnregistered(ctx); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("channel。。。活躍"); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("channel。。。不活躍"); super.channelInactive(ctx); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("channeld讀取完畢。。。"); super.channelReadComplete(ctx); } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { System.out.println("用戶事件觸發。。。"); super.userEventTriggered(ctx, evt); } @Override public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception { System.out.println("channel可寫更改"); super.channelWritabilityChanged(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("補貨到異常"); super.exceptionCaught(ctx, cause); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("助手類添加"); super.handlerAdded(ctx); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { System.out.println("助手類移除"); super.handlerRemoved(ctx); } }
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.25.Final</version> </dependency>
打開瀏覽器:localhost:8088,出現下面錯誤情況,如果用postman工具的話,就會發現不報錯,因為瀏覽器會自動關閉。
解決方案:將super.exceptionCauht(ctx,case);注釋掉就好了
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { //super.exceptionCaught(ctx, cause); }
感謝各位的閱讀,以上就是“Netty中怎么實現前端發送消息,后端接收消息并返回”的內容了,經過本文的學習后,相信大家對Netty中怎么實現前端發送消息,后端接收消息并返回這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。