您好,欢迎来到年旅网。
搜索
您的当前位置:首页Netty专栏——NIO 简单案例群聊

Netty专栏——NIO 简单案例群聊

来源:年旅网

一、需求

  • 1)编写一个NIO群聊系统,实现服务器和客户端之间的简单通讯(非阻塞)
  • 2)实现多人群聊
  • 3)服务器端可以监测用户上线、离线,并实现消息转发功能
  • 4)客户端:通过Channel 可以无阻塞地发送消息给其他用户,同时可以接收其他用户发送的消息

二、案例代码

1、服务端

作两件事:启动服务器并监听8001端口和处理消息。

public class GroupChatServer {
    /**define attributes*/
    private Selector selector;
    private ServerSocketChannel listenChannel;
    private static final int PORT = 8001;
    /**initial*/
    public GroupChatServer(){
        try{
            /*init selector*/
            selector = Selector.open();
            /*init ListenChannel*/
            listenChannel = ServerSocketChannel.open();
            /*bind port*/
            listenChannel.socket().bind(new InetSocketAddress(PORT));
            /*not blocking*/
            listenChannel.configureBlocking(false);
            /*registry listenChannel into selector*/
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);

        }catch (IOException e){
            System.out.println(e.getMessage());
        }
    }

    private void listen(){
        try{
            while (true){
                int count = selector.select();
                if(count>0){
                    Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
                    while (keyIterator.hasNext()){
                        SelectionKey key = keyIterator.next();
                        if(key.isAcceptable()){
                            SocketChannel socketChannel = listenChannel.accept();
                            socketChannel.configureBlocking(false);
                            socketChannel.register(selector, SelectionKey.OP_READ);
                            System.out.println(socketChannel.getRemoteAddress() + "上线");

                        }
                        if(key.isReadable()){
                            readData(key);
                        }
                        keyIterator.remove();
                    }
                }else{
                    System.out.println("waiting----");
                }
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }

    private void readData(SelectionKey key){
        SocketChannel channel = null;
        try{
            channel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int count = channel.read(buffer);
            if(count>0){
                String message = new String(buffer.array());
                System.out.println("===>from client:" + message);
                /*forward message to another client*/
                try {
                    forwardMessage(message,channel);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }

            }
        }catch (IOException e){
            try {
                System.out.println(channel.getRemoteAddress() + "离线了");
                key.cancel();
                channel.close();
            } catch (IOException ioException) {
                System.out.println(ioException.getMessage());
            }
        }
    }

    private void forwardMessage(String msg, SocketChannel self) throws Exception {
        System.out.println("start to reward message");
        for(SelectionKey key : selector.keys()){
            Channel targetChannel = key.channel();
            if(targetChannel instanceof SocketChannel && targetChannel!= self){
                SocketChannel dest = (SocketChannel) targetChannel;
                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8));
                dest.write(buffer);
            }
        }
    }

    public static void main(String[] args) {
        GroupChatServer server = new GroupChatServer();
        server.listen();
    }
}

2、客户端

public class GroupChatClient {

    private final String HOST = "127.0.0.1";
    private final int PORT = 8001;
    private Selector selector;
    private SocketChannel socketChannel;
    private String userName;

    public GroupChatClient() throws Exception {
        selector = Selector.open();
        socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", PORT));
        socketChannel.configureBlocking(false);
        socketChannel.register(selector, SelectionKey.OP_READ);
        userName = socketChannel.getLocalAddress().toString().substring(1);
        System.out.println("Client is ready");
    }

    public void sendInfo(String message){
        message = userName + "say:" +message;
        try{
            socketChannel.write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)));
        }catch (IOException e){
            System.out.println(e.getMessage());
        }
    }

    public void readInfo(){
        try{
            int readerChannels = selector.select();
            if(readerChannels > 0){
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while(iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    if(key.isReadable()){
                        SocketChannel src = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        src.read(buffer);
                        String msg = new String(buffer.array());
                        System.out.println(msg.trim());
                    }
                    iterator.remove();
                }
            }else{

            }
        }catch (IOException e){
            System.out.println(e.getMessage());
        }
    }

    public static void main(String[] args) throws Exception{
        GroupChatClient client = new GroupChatClient();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    client.readInfo();
                    try {
                        Thread.currentThread().sleep(3000);
                    } catch (InterruptedException e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
        }.start();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            String s = scanner.nextLine();
            client.sendInfo(s);
        }
    }
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务