1. 程式人生 > >利用netty簡單實現聊天室

利用netty簡單實現聊天室

1.匯入依賴包

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>5.0.0.Alpha1</version>
        </dependency>

2.netty服務端程式碼

public class NettyServer {
    public static void main(String[] args) {
         EventLoopGroup bossGroup 
= new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap bootStrap = new ServerBootstrap(); ChannelFuture cf; bootStrap.group(bossGroup,workGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG,
1024) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(
"decoder", new StringDecoder());//需要編解碼,否則無法解析 p.addLast("encoder", new StringEncoder()); p.addLast(new NettyServerHandler()); } }); try { cf = bootStrap.bind(8099).sync();//監聽8099埠 System.out.println("8099:binded..."); cf.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } }

3.netty客戶端程式碼

public class NettyClient {
    public static void main(String[] args) throws Exception {
        EventLoopGroup group =new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>(){
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast("decoder", new StringDecoder());
                            p.addLast("encoder", new StringEncoder());
                            p.addLast(new ClientHandler());
                            p.addLast(new ClientHandlerBak());
                        }
                    });

            ChannelFuture future = b.connect("127.0.0.1", 8099).sync();
            future.channel().writeAndFlush("這裡是客戶端,請求連線服務端!");
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }

    }
}

4.服務端處理類

public class NettyServerHandler extends ChannelHandlerAdapter {

    //有客戶端連線時觸發
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("one client connect...");
    }

    //斷開連線時觸發
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("one client disconnect...");
    }

    //接收客戶端傳送的訊息
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客戶端:"+msg.toString());
        InputStreamReader is = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(is);
        String result ="result";
        try{
            result = br.readLine();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        ctx.write(result);//給客戶端回覆
        ctx.flush();
    }
}

5.客戶端處理類

public class ClientHandler extends ChannelHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Client01Handler Active");
        /*若把這一句註釋掉將無法將event傳遞給下一個ClientHandler,例如例子中p.addLast(new Client01Handler())後面緊跟著p.addLast(new Client02Handler())
         後面的Client02Handler裡的方法就不會被觸發。
        */
        ctx.fireChannelActive();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服務端: "+msg);
        InputStreamReader is = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(is);
        String result ="result";
        try{
            result = br.readLine();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        ctx.write(result);//給服務端回覆
        ctx.flush();
    }

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

6.最後,看看效果,先啟動服務端,再啟動客戶端