자바 NIO 채 팅 방 의 예제 코드 구현(단체 채 팅+개인 채 팅)

16154 단어 JavaNIO채 팅 방
기능 소개
기능:단체 채 팅+비공개+온라인 알림+오프라인 알림+온라인 사용자 조회
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
문건
Utils
Maven 으로 다음 가방 두 개 가 져 와 야 합 니 다.

 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

package moremorechat_nio;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * @author mazouri
 * @create 2021-05-09 22:26
 */
@Slf4j
public class Utils {
    /**
     *           
     *
     * @param buf
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Message decode(byte[] buf) throws IOException, ClassNotFoundException {
        ByteArrayInputStream bais = new ByteArrayInputStream(buf);
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Message) ois.readObject();
    }

    /**
     *           
     *
     * @param message
     * @return
     */
    public static byte[] encode(Message message) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(message);
        oos.flush();
        return baos.toByteArray();
    }
}

FinalValue

package moremorechat_nio;
/**
 * @author mazouri
 * @create 2021-05-05 21:00
 */
public final class FinalValue {
    /**
     *     
     */
    public static final int MSG_SYSTEM = 0;
    /**
     *     
     */
    public static final int MSG_GROUP = 1;
    /**
     *     
     */
    public static final int MSG_PRIVATE = 2;
    /**
     *          
     */
    public static final int MSG_ONLINE = 3;
    /**
     *               
     */
    public static final int MSG_NAME = 4;
}
Message

package moremorechat_nio;

import java.io.Serializable;

/**
 * @author mazouri
 * @create 2021-05-05 21:00
 */
public class Message implements Serializable {
    public int type;
    public String message;

    public Message() {
    }

    public Message(String message) {
        this.message = message;
    }

    public Message(int type, String message) {
        this.type = type;
        this.message = message;
    }

    @Override
    public String toString() {
        return "Message{" +
                "type=" + type +
                ", message='" + message + '\'' +
                '}';
    }
}

NioServer

package moremorechat_nio;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static moremorechat_nio.FinalValue.*;

/**
 * ctrl+f12   
 * ctrl+alt+  
 * @author mazouri
 * @create 2021-05-09 19:24
 */
@Slf4j
public class NioServer {
    private Selector selector;
    private ServerSocketChannel ssc;

    public NioServer() {
        try {
            //    selector,      channel
            selector = Selector.open();
            //  ServerSocketChannel,          ,             
            ssc = ServerSocketChannel.open();
            ssc.bind(new InetSocketAddress(8888));
            //          
            ssc.configureBlocking(false);
            // 2.    selector   channel    (  )
            // SelectionKey          ,            channel   
            // ServerSocketChannel   Reactor        Selector ,  ACCEPT  
            ssc.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        NioServer server = new NioServer();
        log.debug("server    ,      ...");
        try {
            server.listen();
        } catch (Exception e) {
            log.debug("       ");
        }
    }

    /**
     *        
     *
     * @throws Exception
     */
    private void listen() throws Exception {
        while (true) {
            // select   ,       ,    ,   ,        ,   Selector select()                (              )
            //  Selector select()                (              )
            // select        ,     ,          ,    ,      
            selector.select();
            //     , selectedKeys             
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                //   key  ,   selectedKeys      ,           
                iterator.remove();
                //       
                if (key.isAcceptable()) {
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel sc = channel.accept();
                    sc.configureBlocking(false);
                    sc.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    dealReadEvent(key);
                }
            }
        }
    }

    /**
     *      
     *
     * @param key
     */
    private void dealReadEvent(SelectionKey key) {
        SocketChannel channel = null;
        try {
            channel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int read = channel.read(buffer);
            //        ,read          -1
            if (read == -1) {
                //cancel        selector    channel,   keys       key          
                key.cancel();
            } else {
                buffer.flip();
                Message msg = Utils.decode(buffer.array());
                log.debug(msg.toString());
                dealMessage(msg, key, channel);
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println((key.attachment() == null ? "    " : key.attachment()) + "    ..");
            dealMessage(new Message(MSG_SYSTEM, key.attachment() + "    .."), key, channel);
            //    
            key.cancel();
            //    
            try {
                channel.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }

    /**
     *       ,       
     *
     * @param msg
     * @param key
     * @param channel
     */
    private void dealMessage(Message msg, SelectionKey key, SocketChannel channel) {
        switch (msg.type) {
            case MSG_NAME:
                key.attach(msg.message);
                log.debug("  {}   ", msg.message);
                getConnectedChannel(channel).forEach(selectionKey -> {
                    SocketChannel sc = (SocketChannel) selectionKey.channel();
                    sendMsgToClient(new Message("        : " + msg.message + "   "), sc);
                });
                break;
            case MSG_GROUP:
                getConnectedChannel(channel).forEach(selectionKey -> {
                    SocketChannel sc = (SocketChannel) selectionKey.channel();
                    sendMsgToClient(new Message(key.attachment() + "          : " + msg.message), sc);
                });
                break;
            case MSG_PRIVATE:
                String[] s = msg.message.split("_");
                AtomicBoolean flag = new AtomicBoolean(false);
                getConnectedChannel(channel).stream().filter(sk -> s[0].equals(sk.attachment())).forEach(selectionKey -> {
                    SocketChannel sc = (SocketChannel) selectionKey.channel();
                    sendMsgToClient(new Message(key.attachment() + "         : " + s[1]), sc);
                    flag.set(true);
                });
                if (!flag.get()){
                    sendMsgToClient(new Message(s[1]+"     ,     !!!"), channel);
                }

                break;
            case MSG_ONLINE:
                ArrayList<String> onlineList = new ArrayList<>();
                onlineList.add((String) key.attachment());
                getConnectedChannel(channel).forEach(selectionKey -> onlineList.add((String) selectionKey.attachment()));
                sendMsgToClient(new Message(onlineList.toString()), channel);
                break;
            case MSG_SYSTEM:
                getConnectedChannel(channel).forEach(selectionKey -> {
                    SocketChannel sc = (SocketChannel) selectionKey.channel();
                    sendMsgToClient(new Message("        : " + msg.message), sc);
                });
                break;
            default:
                break;
        }
    }

    /**
     *         
     *
     * @param msg
     * @param sc
     */
    private void sendMsgToClient(Message msg, SocketChannel sc) {
        try {
            byte[] bytes = Utils.encode(msg);
            sc.write(ByteBuffer.wrap(bytes));
        } catch (IOException e) {
            log.debug("sendMsgToClient       ");
        }
    }

    /**
     *     channel,     
     *
     * @param channel
     * @return
     */
    private Set<SelectionKey> getConnectedChannel(SocketChannel channel) {
        return selector.keys().stream()
                .filter(item -> item.channel() instanceof SocketChannel && item.channel().isOpen() && item.channel() != channel)
                .collect(Collectors.toSet());
    }
}

NioClient

package moremorechat_nio;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

import static moremorechat_nio.FinalValue.*;

/**
 * @author mazouri
 * @create 2021-04-29 12:02
 */
@Slf4j
public class NioClient {
    private Selector selector;
    private SocketChannel socketChannel;
    private String username;
    private static Scanner input;

    public NioClient() throws IOException {
        selector = Selector.open();
        socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8888));
        socketChannel.configureBlocking(false);
        socketChannel.register(selector, SelectionKey.OP_READ);
        log.debug("client    ......");
        log.debug("           ");
        input = new Scanner(System.in);
        username = input.next();
        log.debug("  {}      ", username);
    }

    public static void main(String[] args) throws IOException {
        System.out.println("tips: 
1.
2. @ :
3. "); NioClient client = new NioClient(); // new Thread(() -> { try { client.acceptMessageFromServer(); } catch (Exception e) { e.printStackTrace(); } }, "receiveClientThread").start(); // sendMessageToServer, client.sendMessageToServer(); } /** * * * @throws IOException */ private void sendMessageToServer() throws IOException { // Message message = new Message(MSG_NAME, username); byte[] bytes = Utils.encode(message); socketChannel.write(ByteBuffer.wrap(bytes)); while (input.hasNextLine()) { String msgStr = input.next(); Message msg; boolean isPrivate = msgStr.startsWith("@"); if (isPrivate) { int idx = msgStr.indexOf(":"); String targetName = msgStr.substring(1, idx); msgStr = msgStr.substring(idx + 1); msg = new Message(MSG_PRIVATE, targetName + "_" + msgStr); } else if (" ".equals(msgStr)) { msg = new Message(MSG_ONLINE, " "); } else { msg = new Message(MSG_GROUP, msgStr); } byte[] bytes1 = Utils.encode(msg); socketChannel.write(ByteBuffer.wrap(bytes1)); } } /** * */ private void acceptMessageFromServer() throws Exception { while (selector.select() > 0) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); if (key.isReadable()) { SocketChannel sc = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); sc.read(buffer); Message message = Utils.decode(buffer.array()); log.debug(String.valueOf(message.message)); } } } } }
자바 가 NIO 채 팅 방 을 실현 하 는 예제 코드(단체 채 팅+개인 채 팅)에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 NIO 채 팅 방 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기