Selaa lähdekoodia

feat:数据交互使用自定义的Messag对象,并定义对应的操作,重构实现信息广播和群聊,上线信息提示,加入用户机制,为私聊功能留出扩展

yang yi 2 kuukautta sitten
vanhempi
säilyke
bdc12dc29d

+ 18 - 3
chat-gwng/chat-client/src/main/java/space/anyi/chatClient/Client.java

@@ -3,6 +3,7 @@ package space.anyi.chatClient;
 import space.anyi.chatCommom.Encoder;
 import space.anyi.chatCommom.Message;
 
+import java.awt.*;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
@@ -34,17 +35,31 @@ public class Client {
         socketChannel.register(selector, SelectionKey.OP_READ);
         ReadHandler readHandler = new ReadHandler(selector);
         new Thread(readHandler).start();
-
+        boolean nameFlag = false;
         Scanner scanner = new Scanner(System.in);
+        String username = "";
         while(true){
+            //第一次连接需要输入用户名
+            if (!nameFlag){
+                System.out.println("请输入用户名:");
+                String name = scanner.nextLine();
+                Message message = new Message();
+                message.setSource(name);
+                message.setTarget("server");
+                message.setType(Message.MessageType.SYSTEM);
+                message.setOperate(Message.OperateType.LOGIN);
+                byte[] bytes = Encoder.encode(message);
+                socketChannel.write(ByteBuffer.wrap(bytes));
+                username = name;
+            }
             String line = scanner.nextLine();
             if ("exit".equals(line)){
                 break;
             }
             Message message = new Message();
-            message.setSource("client");
+            message.setSource(username);
             message.setContent(line);
-            message.setTarget("group");
+            message.setTarget(Message.MessageTarget.GROUP);
             byte[] bytes = Encoder.encode(message);
             socketChannel.write(ByteBuffer.wrap(bytes));
         }

+ 20 - 0
chat-gwng/chat-commom/src/main/java/space/anyi/chatCommom/Message.java

@@ -34,4 +34,24 @@ public class Message implements Serializable {
     private String target = "";
     //时间戳
     private Long timeStamp = System.currentTimeMillis();
+
+    public static class MessageType{
+        public static final int SYSTEM = 0;
+        public static final int USER = 1;
+    }
+    public static class OperateType{
+        //服务操作:有客户登陆;客户端操作:需要重新登陆
+        public static final int LOGIN = 1;
+    }
+
+    /**
+     * 信息的来源和目标类型
+     * @author 杨逸
+     * @date 2025/09/24 11:23:31
+     */
+    public static class MessageTarget{
+        public static final String SERVER = "SERVER";
+        public static final String CLIENT = "CLIENT";
+        public static final String GROUP = "GROUP";
+    }
 }

+ 0 - 2
chat-gwng/chat-server/src/main/java/space/anyi/chatServer/ChatServer.java

@@ -6,12 +6,10 @@ import space.anyi.chatCommom.Message;
 import java.io.Closeable;
 import java.io.IOException;
 import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
-import java.nio.charset.StandardCharsets;
 import java.util.Objects;
 import java.util.Set;
 

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

@@ -12,6 +12,8 @@ import java.nio.channels.SelectableChannel;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -26,6 +28,7 @@ import java.util.Set;
 public class ReadHandler implements Runnable, Closeable {
     private Selector readSelector;
     private WriteHandler writeHandler;
+    private Map<String,SocketChannel> userChannels = new HashMap<>();
     private boolean isExit = false;
 
     public ReadHandler(Selector readSelector) {
@@ -74,11 +77,40 @@ public class ReadHandler implements Runnable, Closeable {
                                 int size = byteBuffer.getInt();
                                 byteBuffer = ByteBuffer.allocate(size);
                                 len = socketChannel.read(byteBuffer);
-                                //byteBuffer.flip();
                                 Message message = Encoder.decode(byteBuffer);
-                                //System.out.println(msg);
-                                //转发信息
-                                writeHandler.sendMessageWithGroup(message, socketChannel);
+                                //信息处理
+                                if (message.getType() == Message.MessageType.USER) {
+                                    //用户信息
+                                    {
+                                        //转发信息
+                                        writeHandler.sendMessageWithGroup(message, socketChannel);
+                                    }
+                                }else{
+                                    //系统消息
+                                    switch (message.getOperate()){
+                                        case Message.OperateType.LOGIN:
+                                            //登录
+                                            String username = message.getSource();
+                                            if (userChannels.containsKey(username) && Message.MessageTarget.SERVER.equals(username)) {
+                                                //用户名重复
+                                            }else{
+                                                //用户名保存到对应的selectionKey上,之后需要可以从里面取出
+                                                selectionKey.attach(username);
+                                                //保存用户名到连接的映射
+                                                userChannels.put(username, socketChannel);
+                                                //广播用户上线
+                                                message = new Message();
+                                                message.setSource(Message.MessageTarget.SERVER);
+                                                message.setTarget(Message.MessageTarget.GROUP);
+                                                message.setContent(username+"上线了");
+                                                writeHandler.sendMessageWithGroup(message, socketChannel);
+                                            }
+                                            break;
+                                        default:
+                                            System.err.println("未知操作");
+                                            System.err.println(message);
+                                    }
+                                }
                             }
                         } catch (SocketException e) {
                             //连接意外中断导致异常