基于netty的简单群聊代码

服务器:

package GroupChat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
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 GroupChatServer {
    //设置端口号
    private int port;

    //通过构造函数传入端口号
    public GroupChatServer(int port) {
        this.port = port;
    }

    //启动方法
    public void run() {
        //创建两个事件循环组
        //创建bossGroup
        NioEventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();
        //创建workerGroup
        NioEventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap bootstrap = new ServerBootstrap();
            //配置参数
            bootstrap.group(bossEventLoopGroup, workerEventLoopGroup)
                    .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 {
                            //获取通道pipeline
                            ChannelPipeline channelPipeline = socketChannel.pipeline();
                            //加入解码器
                            channelPipeline.addLast("decoder", new StringDecoder());
                            //加入编码器
                            channelPipeline.addLast("encoder", new StringEncoder());
                            //加入业务处理handler
                            channelPipeline.addLast(new GroupChatServerHandler());
                        }
                    });
            //输出提示信息
            System.out.println("netty 服务器启动~~");
            //获取netty异步监听器
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            //关闭监听
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossEventLoopGroup.shutdownGracefully();
            workerEventLoopGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {

        new GroupChatServer(7000).run();

    }
}

服务器Handler:

package GroupChat;

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 GroupChatServerHandler extends SimpleChannelInboundHandler<String> {
    //定义一个channel组管理所有的channel
    //GlobalEventExecutor.INSTANCE全局事件执行器,单例
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //转发消息提醒,并将该channel加入channelGroup
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //将该客户端加入群聊的信息转发给其他客户端
        Channel channel = ctx.channel();
        //channelGroup会自动遍历所有的channel并发送消息
        channelGroup.writeAndFlush("[客户端]" + channel.remoteAddress() + "\t加入群聊~~");
        channelGroup.add(channel);
    }

    //该方法表示channel断开连接,会自动将channel从channel从channelGroup中删除
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush("[客户端]" + ctx.channel().remoteAddress() + "\t退出群聊~");
    }

    //该方法表示channel处于活动状态
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "\t上线了~~");
    }

    //该方法表示channel处于非活动状态
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "\t离线了~");
    }

    //该方法主要用于数据读取传输
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        //获取当前的channel
        Channel channel = ctx.channel();
        //将信息转发给其他客户端,即排除自己
        channelGroup.forEach(ch -> {
            if (channel != ch) {
                ch.writeAndFlush("[客户端]" + channel.remoteAddress() + "\t" + msg);
            }
        });
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //关闭通道
        ctx.close();
        cause.printStackTrace();
    }

}

客户端:

package GroupChat;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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 GroupChatClient {
    //属性定义
    private final String host;
    private final int port;

    public GroupChatClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void run() {
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();


        try {
            Bootstrap bootstrap = new Bootstrap()
                    .group(eventExecutors)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {

                            socketChannel.pipeline().addLast("decoder", new StringDecoder())
                                    .addLast("encoder", new StringEncoder())
                                    .addLast(new GroupChatClientHandler());
                        }
                    });
            ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
            Channel channel = channelFuture.channel();
            System.out.println("----------" + channel.remoteAddress() + "----------");
            //创建一个扫描器输入信息
            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 {
            eventExecutors.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new GroupChatClient("127.0.0.1", 7000).run();
    }
}

客户端Handler:

package GroupChat;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {
        System.out.println(msg.trim());
    }
}

发布了61 篇原创文章 · 获赞 0 · 访问量 288

猜你喜欢

转载自blog.csdn.net/weixin_43490369/article/details/104732500