server 端代码
import com.chinadaas.bio.chinadaasbio.groupChart.handler.ServerHandler;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;public class Server { private Integer PORT; public Server(Integer PORT) { this.PORT = PORT; } public void run() { NioEventLoopGroup boosGroup = new NioEventLoopGroup(1); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(boosGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); // 退出解码器 pipeline.addLast("myDecoder", new StringDecoder()); // 退出编码器 pipeline.addLast("myEncoder", new StringEncoder()); pipeline.addLast(new ServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(PORT).sync(); channelFuture.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { boosGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) { Server server = new Server(8886); server.run(); }}
client端代码
import com.chinadaas.bio.chinadaasbio.groupChart.handler.ClientHandler;import io.netty.bootstrap.Bootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;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;public class Client { private final String HOST; private final Integer PORT; public Client(String host, Integer port) { this.HOST = host; this.PORT = port; } public void run() { NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(workerGroup) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); // 解码器 pipeline.addLast("myDecoder", new StringDecoder()); // 编码器 pipeline.addLast("myEncoder", new StringEncoder()); pipeline.addLast(new ClientHandler()); } }); ChannelFuture channelFuture = bootstrap.connect(HOST, PORT).sync(); Channel channel = channelFuture.channel(); Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { String msg = scanner.nextLine(); channel.writeAndFlush(msg + "\r\n"); } channelFuture.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { workerGroup.shutdownGracefully(); } } public static void main(String[] args) { Client client = new Client("127.0.0.1", 8886); client.run(); }}
ServerHandler 代码
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;public class ServerHandler extends SimpleChannelInboundHandler<String> { /** * GlobalEventExecutor.INSTANCE 全局事件执行器 * */ private static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel() + "上线了"); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel() + "离线了"); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); CHANNEL_GROUP.writeAndFlush("[客户端]" + channel.remoteAddress() + "退出群聊"); CHANNEL_GROUP.add(channel); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); CHANNEL_GROUP.writeAndFlush("[客户端]" + channel.remoteAddress() + "来到群聊"); } @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { // 获取音讯并转发到群聊中其余的人 Channel channel = channelHandlerContext.channel(); CHANNEL_GROUP.forEach(ch -> { if (ch != channel) { ch.writeAndFlush("[客户" + channel.remoteAddress() + "]说:" + s + "\n"); } else { ch.writeAndFlush("我说:" + s + "\n"); } }); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); }}
ClientHandler 代码
import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class ClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { System.out.println(s.trim()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); }}
前面还有优化,以后只是大抵实现以下