netty框架--实现一个聊天功能

netty框架--实现一个聊天功能。

最近在学习netty框架,netty框架为异步非阻塞IO框架,比起传统的BIO,性能,并发性更为可靠。

如下为一个netty的聊天小程序:

首先编写客户端启动类 ChatClient.java

import java.io.BufferedReader;
import java.io.InputStreamReader;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

public class ChatClient {

    private final int port;
    private final String host;

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

    }

    public void run() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();

        try {

            Bootstrap b = new Bootstrap();

            b.group(group).channel(NioSocketChannel.class).handler(new ChatChannelInitializer());

            Channel channel = b.connect(host, port).sync().channel();

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

            while (true) {
                String msg = in.readLine();
                channel.writeAndFlush( msg+ "\r\n");
            }

        } finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new ChatClient("10.0.90.93",8080).run();
    }
}

添加通道初始化类 ChatChannelInitializer,添加各种处理类及本的处理类。

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class ChatChannelInitializer extends ChannelInitializer<Channel> {

    @Override
    protected void initChannel(Channel ch) throws Exception {

        ChannelPipeline p = ch.pipeline();
        
        p.addLast("framer",new DelimiterBasedFrameDecoder(1024,Delimiters.lineDelimiter()));
        p.addLast("StringDecoder",new StringDecoder());
        p.addLast("StringEncoder",new StringEncoder());
        
        p.addLast("handler",new ChatClientHander());
        
    }

}

 

通道I/O处理类 ChatHandler

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

public class ChatClientHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        System.out.println(msg);

    }

}

服务端编写:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class ChatServer {

    private final int port;

    public ChatServer(int port) {
        this.port = port;

    }
    
    public void run() throws Exception
    {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        
        
        
        try {
            
            ServerBootstrap b = new ServerBootstrap();
            
            b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChatServerInitializer());
                    
            b.bind(port).sync().channel().closeFuture().sync();
            
        } finally {

            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new ChatServer(8080).run();
    }
}

 

package com.phei.netty.chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class ChatServerInitializer extends ChannelInitializer<Channel> {

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline p = ch.pipeline();
        p.addLast("framer",new DelimiterBasedFrameDecoder(1024,Delimiters.lineDelimiter()));
        p.addLast("StringDecoder", new StringDecoder());
        p.addLast("StringEncoder", new StringEncoder());
        
        p.addLast("handler", new ChatServerHandler());
    }

}

 

 服务端处理类,此类服务监听各Chat客户端的连入,退出,以及分发客户端发送的消息等。

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.DefaultEventExecutorGroup;

public class ChatServerHandler extends SimpleChannelInboundHandler<String> {

    private final static ChannelGroup channels = new DefaultChannelGroup(new DefaultEventExecutorGroup(1).next());

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        Channel incoming = ctx.channel();

        for (Channel ch : channels) {
            if (ch != incoming) {
                ch.writeAndFlush("[" + incoming.remoteAddress() + "] - " + msg + "\r\n");
            }
        }

    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        
        
        Channel channel = ctx.channel();
        for(Channel ch :channels)
        {
            ch.writeAndFlush("[SERVER] - "+channel.remoteAddress() +" has joined.\r\n");
        }
        
        channels.add(channel);
        
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        for(Channel ch :channels)
        {
            ch.writeAndFlush("[SERVER] - "+channel.remoteAddress() +" has left.\r\n");
        }
        
        channels.remove(channel);
    }

}

 

posted @ 2018-03-27 17:14  格里高利  阅读(246)  评论(0)    收藏  举报