效果图:
服务端:
package cn.itcast.netty.chat; 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.util.ArrayList; import java.util.List; //自定义一个服务器端业务处理类 public class ChatServerHandler extends SimpleChannelInboundHandler<String> { public static List<Channel> channels = new ArrayList<>(); @Override //通道就绪 public void channelActive(ChannelHandlerContext ctx) { Channel inChannel=ctx.channel(); channels.add(inChannel); System.out.println("[Server]:"+inChannel.remoteAddress().toString().substring(1)+"上线"); } @Override //通道未就绪 public void channelInactive(ChannelHandlerContext ctx) { Channel inChannel=ctx.channel(); channels.remove(inChannel); System.out.println("[Server]:"+inChannel.remoteAddress().toString().substring(1)+"离线"); } @Override //读取数据 protected void channelRead0(ChannelHandlerContext ctx, String s) { Channel inChannel=ctx.channel(); for(Channel channel:channels){ if(channel!=inChannel){ channel.writeAndFlush("["+inChannel.remoteAddress().toString().substring(1)+"]"+"说:"+s+"\n"); } } } }
package cn.itcast.netty.chat; 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.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; //聊天程序服务器端 public class ChatServer { private int port; //服务器端端口号 public ChatServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) { ChannelPipeline pipeline=ch.pipeline(); //往pipeline链中添加一个解码器 pipeline.addLast("decoder",new StringDecoder()); //往pipeline链中添加一个编码器 pipeline.addLast("encoder",new StringEncoder()); //往pipeline链中添加自定义的handler(业务处理类) pipeline.addLast(new ChatServerHandler()); } }); System.out.println("Netty Chat Server启动......"); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); System.out.println("Netty Chat Server关闭......"); } } public static void main(String[] args) throws Exception { new ChatServer(9999).run(); } }
客户端:
package cn.itcast.netty.chat; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; //自定义一个客户端业务处理类 public class ChatClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { System.out.println(s.trim()); } }
package cn.itcast.netty.chat; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Scanner; //聊天程序客户端 public class ChatClient { private final String host; //服务器端IP地址 private final int port; //服务器端端口号 public ChatClient(String host, int port) { this.host = host; this.port = port; } public void run(){ EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch){ ChannelPipeline pipeline=ch.pipeline(); //往pipeline链中添加一个解码器 pipeline.addLast("decoder",new StringDecoder()); //往pipeline链中添加一个编码器 pipeline.addLast("encoder",new StringEncoder()); //往pipeline链中添加自定义的handler(业务处理类) pipeline.addLast(new ChatClientHandler()); } }); ChannelFuture cf=bootstrap.connect(host,port).sync(); Channel channel=cf.channel(); System.out.println("------"+channel.localAddress().toString().substring(1)+"------"); Scanner scanner=new Scanner(System.in); channel.writeAndFlush("我是一个客户端"); while (scanner.hasNextLine()){ String msg=scanner.nextLine(); channel.writeAndFlush(msg+"\r\n"); } } catch (Exception e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new ChatClient("127.0.0.1",9999).run(); } }
package cn.itcast.netty.chat; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Scanner; //聊天程序客户端 public class ChatClient { private final String host; //服务器端IP地址 private final int port; //服务器端端口号 public static Channel channel; public ChatClient(String host, int port) { this.host = host; this.port = port; } public void run(){ EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch){ ChannelPipeline pipeline=ch.pipeline(); //往pipeline链中添加一个解码器 pipeline.addLast("decoder",new StringDecoder()); //往pipeline链中添加一个编码器 pipeline.addLast("encoder",new StringEncoder()); //往pipeline链中添加自定义的handler(业务处理类) pipeline.addLast(new ChatClientHandler()); } }); ChannelFuture cf=bootstrap.connect(host,port).sync(); channel=cf.channel(); System.out.println("------"+channel.localAddress().toString().substring(1)+"------"); channel.writeAndFlush("run方法"); // Scanner scanner=new Scanner(System.in); // while (scanner.hasNextLine()){ // String msg=scanner.nextLine(); // channel.writeAndFlush(msg+"\r\n"); // } } catch (Exception e) { e.printStackTrace(); } finally { //group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new ChatClient("127.0.0.1",9999).run(); channel.writeAndFlush("clinet-main方法"); } }