Netty案例介绍-群聊案例实现
生活随笔
收集整理的這篇文章主要介紹了
Netty案例介绍-群聊案例实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
??前面介紹了基于Netty的Http服務,本文我們來通過Netty來實現群聊案例。
群聊案例
1.案例需求
目的:進一步理解Netty非阻塞網絡編程機制
2.服務端代碼
2.1 服務端處理器
??在服務端處理器中我們要處理客戶端的上下線及消息的分發
package com.dpb.netty.goupchat;import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.GlobalEventExecutor;import java.text.SimpleDateFormat; import java.util.Date;/*** @program: netty4demo* @description: 群聊服務處理器* 1.客戶端連接 提示其他客戶端上線* 2.客戶端發送消息,需要將詳細轉發給其他客戶端* @author: 波波烤鴨* @create: 2019-12-29 14:02*/ public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {// 管理所有客戶端的Channel 是一個單例對象private static final ChannelGroup grouup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");/*** 客戶端連接觸發的方法* @param ctx* @throws Exception*/@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {// 獲取當前連接對象的 Channel對象Channel channel = ctx.channel();// 通知其他客戶端 當前客戶端連接上線了grouup.writeAndFlush("[客戶端上線了]" + channel.remoteAddress() + " 上線了 " + sdf.format(new Date()) + "\n");// 將當前channel添加到 channelGroup中grouup.add(channel);}/*** 客戶端斷開連接觸發的方法* @param ctx* @throws Exception*/@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {// 通知其他客戶端 我離線了ctx.writeAndFlush("[客戶端下線了]" + ctx.channel().remoteAddress() + " : " + sdf.format(new Date())+ "\n");}/*** 讀取客戶端請求消息的方法* @param context* @param s* @throws Exception*/@Overrideprotected void channelRead0(ChannelHandlerContext context, String s) throws Exception {// 獲取當前的 handlerChannel channel = context.channel();// 遍歷channelGroupgrouup.forEach(ch ->{if(ch == channel){// 是自己ch.writeAndFlush( "我說:" + s);}else{// 不是自己ch.writeAndFlush(channel.remoteAddress() + "說:" + s);}});} }2.2 服務端
??服務端我們要啟動我們的服務,綁定端口等。
package com.dpb.netty.goupchat;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;/*** @program: netty4demo* @description: 群聊系統服務端* @author: 波波烤鴨* @create: 2019-12-29 13:50*/ public class GroupChatServer {// 服務的端口號private int port;public GroupChatServer(int port){this.port = port;}/*** 服務運行的方法*/public void run() throws Exception{// 創建BossGroup和WorkGroupEventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workGroup = new NioEventLoopGroup();// 創建 ServerBootstrap 服務啟動對象ServerBootstrap bootstrap = new ServerBootstrap();try{// 給bootstrap設置相關的參數bootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,128).childOption(ChannelOption.SO_KEEPALIVE,true).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel sc) throws Exception {// 獲取pipeline對象ChannelPipeline pipeline = sc.pipeline();// 設置對應的handlerpipeline.addLast("docoder",new StringDecoder());pipeline.addLast("encoder",new StringEncoder());pipeline.addLast(new GroupChatServerHandler());}});System.out.println("服務端啟動了.......");// 綁定端口ChannelFuture future = bootstrap.bind(port).sync();future.channel().closeFuture().sync();}finally {bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception{GroupChatServer server = new GroupChatServer(8888);server.run();} }3. 客戶端代碼
3.1 客戶端處理器
??獲取服務器轉發的消息
package com.dpb.netty.goupchat;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;/*** @program: netty4demo* @description: 客戶端處理器* @author: 波波烤鴨* @create: 2019-12-29 14:19*/ public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {/*** 讀取消息* @param channelHandlerContext* @param s* @throws Exception*/@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {System.out.println(s.trim());} }3.2 客戶端代碼
??連接服務器,發送消息
package com.dpb.netty.goupchat;import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;import java.util.Scanner;/*** @program: netty4demo* @description:* @author: 波波烤鴨* @create: 2019-12-29 14:14*/ public class GroupChatClient {public String host;public int port ;public GroupChatClient(String host,int port){this.host = host;this.port = port;}public void run() throws Exception{EventLoopGroup clientGroup = new NioEventLoopGroup(1);Bootstrap bootstrap = new Bootstrap();try{bootstrap.group(clientGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel sc) throws Exception {sc.pipeline().addLast("decoder",new StringDecoder());sc.pipeline().addLast("encoder",new StringEncoder());sc.pipeline().addLast(new GroupChatClientHandler());}});ChannelFuture future = bootstrap.connect(host, port).sync();Channel channel = future.channel();// 發送消息Scanner scanner = new Scanner(System.in);while(scanner.hasNextLine()){String msg = scanner.nextLine();channel.writeAndFlush(msg + "\n");}}finally {clientGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {GroupChatClient client = new GroupChatClient("localhost",8888);client.run();} }4.測試
??啟動服務器,然后啟動多個客戶端查看效果
查看效果,功能實現~
總結
以上是生活随笔為你收集整理的Netty案例介绍-群聊案例实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MATLAB——小球碰撞
- 下一篇: 了解数据库索引及其原理