Переглянути джерело

feat:服务端使用WriteHandler进行数据的发送,实现广播和群聊

yang yi 2 місяців тому
батько
коміт
7f27b43129

+ 12 - 18
chat-gwng/chat-server/src/main/java/space/anyi/chatServer/ChatServer.java

@@ -28,6 +28,7 @@ public class ChatServer implements Runnable, Closeable {
     private Selector acceptSelector;
     private Selector readSelector;
     private ReadHandler readHandler;
+    private WriteHandler writeHandler;
     private boolean isExit = false;
 
     public ChatServer(int port) throws IOException {
@@ -42,6 +43,9 @@ public class ChatServer implements Runnable, Closeable {
         this.readSelector = Selector.open();
         //自定义读事件处理器,用处理客户端发送的消息
         this.readHandler = new ReadHandler(readSelector);
+        this.writeHandler = new WriteHandler(readSelector);
+        //读取到数据后需要,写数据的能力
+        readHandler.setWriteHandler(writeHandler);
     }
 
 
@@ -102,42 +106,32 @@ public class ChatServer implements Runnable, Closeable {
      * @data:2025/09/22 19:25:58
      * @since 1.0.0
      */
-    public void broadcast(String msg){
-        //获取所有的key
-        Set<SelectionKey> keys = readSelector.keys();
-        for (SelectionKey key : keys) {
-            SocketChannel channel = (SocketChannel) key.channel();
-            try {
-                //发信息
-                channel.write(ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)));
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
+    public void broadcast(String msg) {
+        writeHandler.broadcast(msg);
     }
 
     /**
      * @param msg 信息
-     * @param target 目标
+     * @param target 目标的channel
      * @description: 发送私聊信息
      * @author: 杨逸
      * @data:2025/09/22 19:31:09
      * @since 1.0.0
      */
-    public void sendMessageWithPrivate(String msg,String target){
-        //todo
+    public void sendMessageWithPrivate(String msg,SocketChannel target){
+        writeHandler.sendMessageWithPrivate(msg,target);
     }
 
     /**
      * @param msg 信息
-     * @param group 群
+     * @param form 发起人的连接channel
      * @description: 群发信息
      * @author: 杨逸
      * @data:2025/09/22 19:32:08
      * @since 1.0.0
      */
-    public void sendMessageWithGroup(String msg,String group){
-        //todo
+    public void sendMessageWithGroup(String msg,SocketChannel form){
+        writeHandler.sendMessageWithGroup(msg,form);
     }
 
     @Override

+ 4 - 1
chat-gwng/chat-server/src/main/java/space/anyi/chatServer/ReadHandler.java

@@ -23,6 +23,7 @@ import java.util.Set;
 @Data
 public class ReadHandler implements Runnable, Closeable {
     private Selector readSelector;
+    private WriteHandler writeHandler;
     private boolean isExit = false;
 
     public ReadHandler(Selector readSelector) {
@@ -81,7 +82,9 @@ public class ReadHandler implements Runnable, Closeable {
                         byteBuffer.flip();
                         if (len > 0) {
                             String msg = new String(byteBuffer.array(), 0, len);
-                            System.out.println(msg);
+                            //System.out.println(msg);
+                            //转发信息
+                            writeHandler.sendMessageWithGroup(msg, socketChannel);
                         }
                     }
                     //处理完,移除selectionKey

+ 91 - 0
chat-gwng/chat-server/src/main/java/space/anyi/chatServer/WriteHandler.java

@@ -0,0 +1,91 @@
+package space.anyi.chatServer;
+
+import lombok.Data;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Set;
+
+/**
+ * @ProjectName: chat-gwng
+ * @FileName: WriteHandler
+ * @Author: 杨逸
+ * @Data:2025/9/22 20:20
+ * @Description:
+ */
+@Data
+public class WriteHandler {
+    //借助selector获取所有的连接channel
+    private Selector selector;
+
+    public WriteHandler(Selector selector) {
+        this.selector = selector;
+    }
+
+    /**
+     * @param msg
+     * @description: 服务端广播信息
+     * @author: 杨逸
+     * @data:2025/09/22 20:28:01
+     * @since 1.0.0
+     */
+    //广播
+    public void broadcast(String msg){
+        //获取所有的key
+        Set<SelectionKey> keys = selector.keys();
+        for (SelectionKey key : keys) {
+            SocketChannel channel = (SocketChannel) key.channel();
+            try {
+                //发信息
+                channel.write(ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * @param msg
+     * @param form
+     * @description: 群发
+     * @author: 杨逸
+     * @data:2025/09/22 20:24:08
+     * @since 1.0.0
+     */
+    //群发
+    public void sendMessageWithGroup(String msg,SocketChannel form){
+        Set<SelectionKey> keys = selector.keys();
+        for (SelectionKey key : keys) {
+            SocketChannel channel = (SocketChannel) key.channel();
+            //不是信息来源才转发
+            if (!channel.equals(form)) {
+                try {
+                    channel.write(ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)));
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * @param msg
+     * @param to
+     * @description:
+     * @author: 杨逸
+     * @data:2025/09/22 20:27:08
+     * @since 1.0.0
+     */
+    //私聊
+    public void sendMessageWithPrivate(String msg,SocketChannel to){
+        try {
+            to.write(ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}