netty简单入门案例

4 篇文章 0 订阅

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>() {
                        @Override
                        protected 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() {
                @Override
                public 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
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("客户端:" + ctx.channel().remoteAddress() + "上线了...");
        channelGroup.add(channel);//把新加入的管道添加到管道组
    }

    /**
     * 客户端离开连接,该方法被触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("客服端:" + channel.remoteAddress() + "下线了...");
    }

    /**
     * 表示channel活动状态,在服务端提示某某某上线了
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress()+"上线了........");
    }

    /**
     * 表示channel不活动状态,在服务端提示某某是离线了
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress()+"离线了........");
    }

    /**
     * 处理信息并且转发
     * @param channelHandlerContext
     * @param msg
     * @throws Exception
     */
    @Override
    protected 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
     */
    @Override
    public 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());//加入编码器
                            //加入自己的handler
                            pipeline.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);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值