分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

03_netty实现聊天室功能

发布时间:2023-09-06 02:31责任编辑:胡小海关键词:暂无标签

【概述】

聊天室主要由两块组成:聊天服务器端(ChatRoomServer)和聊天客户端(ChatClient)。

[ 聊天服务器(ChatRoomServer)功能概述 ]  

1.监听所有客户端的接入、断线

2.有客户端A接入聊天室时,将接入消息发给除了客户端A的其他客户端

3.当客户端A退出聊天室时,将退出消息发给除了客户端A的其他客户端

4.当客户端A发送消息到聊天室时,将消息转发给除了客户端A的其他客户端

[ 聊天客户端(ChatClient)功能概述 ]

1.发送消息至聊天服务器

2.接收聊天服务器发送过来的所有消息

【聊天服务端 ChatRoomServer】

/** * 聊天室服务端 */public class ChatRoomServer { ???private final int port ; ???public ChatRoomServer(int port) { ???????this.port = port; ???} ???public void start(){ ???????EventLoopGroup boss = new NioEventLoopGroup(); ???????EventLoopGroup worker = new NioEventLoopGroup(); ???????try{ ???????????ServerBootstrap bootstrap = new ServerBootstrap(); ???????????bootstrap.group(boss,worker) ???????????????????.channel(NioServerSocketChannel.class) ???????????????????.childHandler(new ChatServerInitialize()) ???????????????????.option(ChannelOption.SO_BACKLOG, 128) ???????????????????.option(ChannelOption.SO_KEEPALIVE, true); ???????????ChannelFuture future = bootstrap.bind(port).sync(); ???????????future.channel().closeFuture().sync(); ???????}catch (Exception e){ ???????????e.printStackTrace(); ???????}finally { ???????????boss.shutdownGracefully(); ???????????worker.shutdownGracefully(); ???????} ???} ???public static void main(String[] args) { ???????new ChatRoomServer(9999).start(); ?//服务端监听本地的9999端口 ???}}

【ChatServerInitialize】

public class ChatServerInitialize extends ChannelInitializer<SocketChannel>{ ???@Override ???protected void initChannel(SocketChannel channel) throws Exception { ???????System.out.println("用户【"+channel.remoteAddress()+"】接入聊天室......"); ???????ChannelPipeline pipeline = channel.pipeline(); ???????pipeline.addLast("framer",new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); ???????pipeline.addLast("decoder",new StringDecoder()); ???????pipeline.addLast("encoder",new StringEncoder()); ???????pipeline.addLast("handler",new ChatServerHandler()); ???}}

【ChatServerHandler】

/** * 聊天服务器对各种情况的处理 */public class ChatServerHandler extends SimpleChannelInboundHandler<String> { ???public static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); ???/** ????* 当从服务端收到新的客户端连接时 ????* 客户端的 Channel 存入 channels 列表中,并通知列表中的其他客户端 Channel ????*/ ???@Override ???public void handlerAdded(ChannelHandlerContext ctx) throws Exception { ???????Channel clientChannel = ctx.channel(); ???????channels.add(clientChannel); ???????for (Channel ch : channels) { ???????????if (ch != clientChannel) { ?//通知除了自己以外的其他用户 ???????????????ch.writeAndFlush("【提示】:用户【" + clientChannel.remoteAddress() + "】进入聊天室...\n"); ???????????} ???????} ???} ???/** ????* 每当从服务端收到客户端断开时 ????* 客户端的 Channel 自动从 channels 列表中移除了,并通知列表中的其他客户端 Channel ????*/ ???@Override ???public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { ???????Channel clientChannel = ctx.channel(); ???????channels.remove(clientChannel); ???????for (Channel ch : channels) { ???????????if (ch != clientChannel) { ?//通知除了自己以外的其他用户 ???????????????ch.writeAndFlush("【提示】:用户【" + clientChannel.remoteAddress() + "】退出聊天室...\n"); ???????????} ???????} ???} ???/** ????* 接受到客户端发出的消息 ????* 判断channel是否是 ????*/ ???@Override ???protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { ???????Channel clientChannel = ctx.channel(); ???????for (Channel ch : channels) { ???????????if (ch != clientChannel) { ???????????????ch.writeAndFlush("用户【" + clientChannel.remoteAddress() + "】说:" + msg + "\n"); ???????????} else { ???????????????ch.writeAndFlush("【我】说:" + msg + "\n"); ???????????} ???????} ???} ???/** ????* 服务端监听到客户端活动 ????*/ ???@Override ???public void channelActive(ChannelHandlerContext ctx) throws Exception { ???????Channel clientChannel = ctx.channel(); ???????System.out.println("用户【"+clientChannel.remoteAddress()+"】在线中..."); ???} ???/** ????* 服务端监听到客户端 不活动 ????*/ ???@Override ???public void channelInactive(ChannelHandlerContext ctx) throws Exception { ???????Channel clientChannel = ctx.channel(); ???????System.out.println("用户【 " +clientChannel.remoteAddress()+"】:离线了"); ???}}

【ChatClient 聊天客户端】

/** * 聊天客户端 */public class ChatClient { ???private final String host; ???private final int port; ???public ChatClient(String host, int port) { ???????this.host = host; ???????this.port = port; ???} ???public void start() { ???????EventLoopGroup worker = new NioEventLoopGroup(); ???????Bootstrap bootstrap = new Bootstrap(); ???????try{ ???????????bootstrap.group(worker) ???????????????????.channel(NioSocketChannel.class) ???????????????????.handler(new ClientInitializer()); ???????????Channel channel ?= bootstrap.connect(host,port).sync().channel(); ???????????//客户端从键盘输入数据 ???????????BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); ???????????while(true){ ???????????????channel.writeAndFlush(input.readLine()+"\n"); ???????????} ???????}catch (Exception e){ ???????????e.printStackTrace(); ???????}finally { ???????????worker.shutdownGracefully(); ???????} ???} ???public static void main(String[] args) { ???????new ChatClient("127.0.0.1",9999).start(); //连接服务器端 ???}}

【ChatClientInitializer 】

public class ChatClientInitializer extends ChannelInitializer<SocketChannel>{ ???@Override ???protected void initChannel(SocketChannel socketChannel) throws Exception { ???????//当有客户端连接服务器时,netty会调用这个初始化器的 initChannel方法 ???????System.out.println("客户端开始初始化......"); ???????ChannelPipeline pipeline = socketChannel.pipeline(); ???????pipeline.addLast("framer",new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); ???????pipeline.addLast("decoder",new StringDecoder()); ???????pipeline.addLast("encoder",new StringEncoder()); ???????pipeline.addLast("handler",new ChatClientHandler()); ???}}

【ChatClientHandler】

public class ChatClientHandler extends SimpleChannelInboundHandler<String> { ???/** ????* 打印服务端发送过来的数据 ????*/ ???@Override ???protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { ???????System.out.println(s); ???}}

【运行结果】

 [1.启动聊天服务器]

[2.启动一个客户端A]

 [3.再启动一个客户端B]

[4.客户端A发送消息]

[5.客户端A关闭]

03_netty实现聊天室功能

原文地址:https://www.cnblogs.com/HigginCui/p/10327568.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved