Netty实现群聊系统
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Netty实现群聊系统
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                1 需求
(1) 編寫一個 Netty群聊系統(tǒng),實現(xiàn)服務器端和客戶端之間的數(shù)據(jù)簡單通訊(非阻塞)
 (2) 實現(xiàn)多人群聊
 (3) 服務器端:可以監(jiān)測用戶上線,離線,并實現(xiàn)消息轉(zhuǎn)發(fā)功能
 (4) 客戶端:通過 channel可以無阻塞發(fā)送消息給其它所有用戶,同時可以接受其它用
 (5) 戶發(fā)送的消息(有服務器轉(zhuǎn)發(fā)得到)
 目的:進一步理解Net非阻塞網(wǎng)絡編程機制
2 Code
2.1 GroupChatConsts
public final class GroupChatConsts {private GroupChatConsts() {}public static final Integer port = 8888;public static final String host = "127.0.0.1";}2.2 GroupChatServer
(1) GroupChatServerHandler
package com.rosh.netty.chat.server;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;/*** @Description:* @Author: rosh* @Date: 2020/12/29 22:59*/ public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {/*** 定義一個channel組,管理所有的channel*/private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 當建立連接時,第一個被執(zhí)行*/@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();//通知其他客戶,有人加入該聊天室channelGroup.writeAndFlush("【客戶端】 " + sdf.format(new Date()) + channel.remoteAddress() + " 加入聊天 \n");//加入聊天channelGroup.add(channel);}/*** 表示channel處于一個活躍的狀態(tài)*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("【" + ctx.channel().remoteAddress() + "】 " + sdf.format(new Date()) + " 上線了 ~");}/*** 表示channel處于不活動的狀態(tài)*/@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("【" + ctx.channel().remoteAddress() + "】 " + sdf.format(new Date()) + " 離線了 ~");}/*** channel斷開連接會被觸發(fā)*/@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channelGroup.writeAndFlush("【客戶端】 " + sdf.format(new Date()) + channel.remoteAddress() + " 離開了\n");}/*** 轉(zhuǎn)發(fā)消息*/@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {Channel channel = ctx.channel();channelGroup.forEach(ch -> {if (channel != ch) {ch.writeAndFlush("【客戶】" + sdf.format(new Date()) + channel.remoteAddress() + "發(fā)送了消息: " + msg + "\n");} else {ch.writeAndFlush("【自己】" + sdf.format(new Date()) + "發(fā)送了消息: " + msg + "\n");}});}/*** 發(fā)生異常時 關(guān)閉通道*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();} }(2) GroupChatServerChannelInitializer
public class GroupChatServerChannelInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//解碼器pipeline.addLast("decoder", new StringDecoder());//編碼器pipeline.addLast("encoder", new StringEncoder());//加入自己業(yè)務handlerpipeline.addLast("serverHandler", new GroupChatServerHandler());} }(3) GroupChatServerHandler
public class GroupChatServer {public static void main(String[] args) {NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup)//nio.channel(NioServerSocketChannel.class)//bossGroup,option,服務端接受連接的隊列長度,如果隊列已滿,客戶端連接將被拒絕。.option(ChannelOption.SO_BACKLOG, 128)//workerGroup,option,是否啟動心跳包活機制.childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new GroupChatServerChannelInitializer());//綁定端口ChannelFuture channelFuture = serverBootstrap.bind(GroupChatConsts.port).sync();//監(jiān)聽關(guān)閉事件channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}2.3 GroupChatClient
(1) GroupChatClientHandler
public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println(msg.trim());} }(2) GroupChatClientChannelInitializetr
public class GroupChatClientChannelInitializetr extends ChannelInitializer<SocketChannel>{@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//解碼器pipeline.addLast("decoder", new StringDecoder());//編碼器pipeline.addLast("encoder", new StringEncoder());//自定義handlerpipeline.addLast("clientHandler", new GroupChatClientHandler());} }(3) GroupChatClient
public class GroupChatClient {public static void main(String[] args) {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new GroupChatClientChannelInitializetr());ChannelFuture channelFuture = bootstrap.connect(GroupChatConsts.host, GroupChatConsts.port).sync();//輸入信息Channel channel = channelFuture.channel();Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String msg = scanner.nextLine();channel.writeAndFlush(msg + "\n");}} catch (InterruptedException e) {e.printStackTrace();} finally {group.shutdownGracefully();}}}3 測試
(1) 啟動服務端,啟動3個客戶端
 
 (2) 發(fā)送消息
 
 
 
總結(jié)
以上是生活随笔為你收集整理的Netty实现群聊系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: matlab三角函数拟合程序,三角函数拟
- 下一篇: 什么是句柄(经典)
