【網路程式設計】NIO,Netty實現群聊Code
阿新 • • 發佈:2020-08-17
筆記回顧
Server
package club.interview.io.netty.chat; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; 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; import io.netty.util.concurrent.GlobalEventExecutor; /** * fixme channel組管理 * @author QuCheng on 2020/8/17. */ public class NettyChatServerStudy1 {public static void main(String[] args) { EventLoopGroup boss = new NioEventLoopGroup(1); EventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(boss, worker) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new MyChatHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(888).sync() .addListener((ChannelFutureListener) future -> { if (future.isSuccess()) { System.out.println("Server is done !"); } }); channelFuture.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } static class MyChatHandler extends SimpleChannelInboundHandler<String> { static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } @Override public void handlerAdded(ChannelHandlerContext ctx) { Channel channel = ctx.channel(); channelGroup.add(channel); String msg = channel.remoteAddress() + " 加入群聊!"; System.out.println("【Log】" + msg); channelGroup.writeAndFlush("【系統提醒】" + msg); } @Override public void handlerRemoved(ChannelHandlerContext ctx) { Channel channel = ctx.channel(); String msg = channel.remoteAddress() + " 退出群聊!"; System.out.println("【Log】" + msg); channelGroup.writeAndFlush("【系統提醒】" + msg); } @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { // 訊息轉發 Channel channel = ctx.channel(); channelGroup.forEach(c -> { String msg2; if (c == channel) { msg2 = "【帥氣的我】" + "\n\t" + msg; } else { msg2 = "【路人】" + c.remoteAddress() + " \n\t" + msg; } System.out.println("【Log】" + msg2); c.writeAndFlush(msg2); }); } } }
Client
package club.interview.io.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.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import java.util.Scanner; /** * @author QuCheng on 2020/8/17. */ public class NettyChatClientStudy1 { public static void main(String[] args) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline() .addLast(new StringDecoder()) .addLast(new StringEncoder()) .addLast(new MyHandler()); } }); ChannelFuture channelFuture = bootstrap.connect("localhost", 888).sync() .addListener(future -> { if (future.isSuccess()) { System.out.println("Client is ok !"); } }); // 發訊息 Scanner scanner = new Scanner(System.in); Channel channel = channelFuture.channel(); while (scanner.hasNextLine()) { channel.writeAndFlush(scanner.nextLine()); } channel.closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } static class MyHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); } } }