Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。我们在网络编程的时候一般都会使用该框架作为基础框架,下面使用netty来实现简单的群聊系统来认识netty的基本使用方法。
服务端:
public class GroupChatServer {private int port;//定义端口信息private GroupChatServer(int port){this.port = port;}private void run() throws Exception{NioEventLoopGroup bossGroup = new NioEventLoopGroup();NioEventLoopGroup workGroup = new NioEventLoopGroup(8);try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class)//设置服务端的通道信息.option(ChannelOption.SO_BACKLOG,128)//设置线程队列连接个数.childOption(ChannelOption.SO_KEEPALIVE,true)//设置活动保持连接的状态.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();//添加对消息处理的编解码器pipeline.addLast(new StringEncoder());//编码器pipeline.addLast(new StringDecoder());//解码器pipeline.addLast(new GroupChatServerHandler());//自定义处理器}});System.out.println("服务端ok...............");//绑定端口ChannelFuture channelFuture = serverBootstrap.bind(port).sync();//添加对异步处理的监听机制channelFuture.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {if(channelFuture.isDone()){System.out.println("操作完成...");}else{System.out.println("操作没有完成");}if(channelFuture.isSuccess()){System.out.println("操作成功...");}else{System.out.println("操作失败...");}}});channelFuture.channel().closeFuture().sync();}finally {bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception{new GroupChatServer(8088).run();}
}
服务端对于的handler:
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {//定义一个管道组来处理所有的管道信息//GlobalEventExecutor.INSTANCE一个单列的全局事件处理器private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);//定义事件格式化工具SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 建立连接会触发该方法,用来在客户端提示某某某上线* @param ctx* @throws Exception*/@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channelGroup.writeAndFlush("客户端:" + ctx.channel().remoteAddress() + "上线了...");channelGroup.add(channel);//把新加入的管道添加到管道组}/*** 客户端离开连接,该方法被触发* @param ctx* @throws Exception*/@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channelGroup.writeAndFlush("客服端:" + channel.remoteAddress() + "下线了...");}/*** 表示channel活动状态,在服务端提示某某某上线了* @param ctx* @throws Exception*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println(ctx.channel().remoteAddress()+"上线了........");}/*** 表示channel不活动状态,在服务端提示某某是离线了* @param ctx* @throws Exception*/@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println(ctx.channel().remoteAddress()+"离线了........");}/*** 处理信息并且转发* @param channelHandlerContext* @param msg* @throws Exception*/@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {Channel channel1 = channelHandlerContext.channel();System.out.println("用户:" + channel1.remoteAddress() + "发送的信息为:" + msg);//开始转发信息for (Channel channel : channelGroup) {if (channel != channel1) {channel.writeAndFlush(sdf.format(new Date()) + "用户:" + channel1.remoteAddress() + "发送的信息为:" + msg);}}}/*** 处理异常信息* @param ctx* @param cause* @throws Exception*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
} |
客户端对于代码:
public class GroupCharClient {//定义端口号和ip地址信息private int port;private String host;/*** 定义加载ip地址和端口号的方法*/public GroupCharClient(String host,int port){this.host = host;this.port = port;}/*** 定义客户端运行的方法*/public void run(){NioEventLoopGroup group = new NioEventLoopGroup();try {//定义客户端启动的方法Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {protected void initChannel(SocketChannel socketChannel) throws Exception {//定义编解码器ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast(new StringDecoder());//加入解码器pipeline.addLast(new StringEncoder());//加入编码器//加入自己的handlerpipeline.addLast(new GroupCharClientHandler());}});System.out.println("客户上线了...");//绑定端口连接ChannelFuture channelFuture = bootstrap.connect(host, port).sync();Channel channel = channelFuture.channel();//客户端输入的信息Scanner scanner = new Scanner(System.in);while(scanner.hasNextLine()){String msg = scanner.next();channel.writeAndFlush(msg);}} catch (Exception e) {e.printStackTrace();} finally {group.shutdownGracefully();}}public static void main(String[] args) {new TestGroupChatClient("127.0.0.1",8088).run();}
}客户度对于的handler:
public class GroupCharClientHandler extends SimpleChannelInboundHandler<String> {/*** 读取服务端转发的消息* @param channelHandlerContext* @param s* @throws Exception*/protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {System.out.println("服务端:" + channelHandlerContext.channel().remoteAddress()+"转发的消息为:"+ s);}
} |