Java Swing νκ²½μ ν
μ€νΈ μ±ν
μ ν리μΌμ΄μ
μΌλ‘, Socket ν΅μ κ³Ό Multi Thread νλ‘κ·Έλλ°μΌλ‘ ꡬνν νλ‘κ·Έλ¨
- κ°λ° νκ²½ λ° μ¬μ© κΈ°μ
- μ€ννλ©΄κ³Ό κΈ°λ₯μ€λͺ
- ꡬν λ°©μ
- μλ² μ ν리μΌμ΄μ
- ν΄λΌμ΄μΈνΈ μ ν리μΌμ΄μ
- κ°λ° νκ²½
- macOS Monterey 12.4
- IntelliJ IDEA
- Java 11
- μ¬μ© κΈ°μ
- Java Network Socket
- AWT, Swing
-
λ‘κ·ΈμΈ νλ©΄
- μ¬μ©μ μμ΄λμ μ΄λ¦μ μ λ ₯νλ νλ©΄
μ¬μ©μ μμ΄λ: νλ‘κ·Έλ¨ λ΄λΆμμ μ¬μ©μλ₯Ό μλ³νλ λ°μ΄ν°μ΄λ¦: μ¬μ©μ λͺ©λ‘κ³Ό μ±ν μ μ λ ₯ν μ¬λμ νμνλ λ°μ΄ν°
-
λ‘λΉ νλ©΄
- λ‘λΉ μ±ν (λͺ¨λ μ¬μ©μ μ±ν κ°λ₯)
- μ±ν νλ‘κ·Έλ¨μ μ μν λͺ¨λ μ¬μ©μ 리μ€νΈ μΆλ ₯
- μ±ν λ°© λͺ©λ‘ μΆλ ₯
-
μ±ν λ°© μμ± νλ©΄
-
μ±ν λ°© νλ©΄
-
ν΄λΉ μ±ν λ°©μ μ μν μ¬μ©μ λͺ©λ‘ μΆλ ₯
-
λκ°κΈ° λ²νΌ ν΄λ¦νλ©΄ μ±ν μ°½μ ν΄μ₯ λ©μμ§ μΆλ ₯λκ³ , μ¬μ©μ λͺ©λ‘ κ°±μ
-
λͺ¨λ μ¬μ©μκ° μ±ν λ°©μμ λκ° κ²½μ°, μ±ν λ°© μ΄λ¦μ λ‘λΉμ μ±ν λͺ©λ‘μμ μ κ±°
-
μ΄λ―Έ μ΄λ €μλ μ±ν λ°©μ λ€μ λ€μ΄κ°λ € ν κ²½μ° μ€λ₯ νμ μΆλ ₯
-
-
μλ²μ ν΄λΌμ΄μΈνΈλ
SocketμΌλ‘ ν΅μ -
ν΄λΌμ΄μΈνΈ
Swingμ μ΄μ©ν΄ νλ©΄μ ꡬμ±Threadλ₯Ό μ΄μ©ν΄ μμ μSocket InputSreamμ μ§μμ μΌλ‘ μ½μ΄μμ μλ²μμ λ³΄λΈ λ©μμ§λ₯Ό μμ
-
μλ²
- κ° ν΄λΌμ΄μΈνΈμ λν
SocketμMulti Threadνκ²½μΌλ‘ κ΄λ¦¬ Multi Threadλ₯Ό μ΄μ©ν΄ λͺ¨λ μ¬μ©μλ€μSocket InputSreamμ μ§μμ μΌλ‘ νμΈ- ν΄λΌμ΄μΈνΈκ° λ³΄λΈ λ©μμ§λ₯Ό λ°νμΌλ‘ μλ²μ μ μ₯λ μλ£κ΅¬μ‘°λ₯Ό μ²λ¦¬νκ³ , μλ΅μ μ μ‘
- κ° ν΄λΌμ΄μΈνΈμ λν
-
ν΄λΌμ΄μΈνΈμ μλ²λ λ¬Έμμ΄ λ©μμ§λ₯Ό μ£Όκ³ λ°μΌλ©°, μ£Όκ³ λ°λ μλ£κ΅¬μ‘°λ νμμ λ°λΌ λͺ¨λ λ¬Έμμ΄λ‘ μΉν
-
μμͺ½μμ λμΌν
Request Response DTOλ₯Ό κ°μ§κ³ μμ§λ§ ν΄λΌμ΄μΈνΈμ κ²½μ°Request DTO β StringμΌλ‘ λ³κ²½ν΄μ μ‘μ νκ³ ,μλ²λ μ΄λ₯Ό λ°μ νμ±νμ¬
String β Request DTOλ₯Ό μμ±ν΄ μ¬μ©μλ²λ λ§μ°¬κ°μ§λ‘ ν΄λΌμ΄μΈνΈλ‘ λ©μμ§λ₯Ό λ³΄λΌ κ²½μ°
Response DTOκ°μ²΄λ₯Ό μμ±ν΄ μ λ¬ν λ΄μ©μΌλ‘ μΈμ€ν΄μ€λ₯Ό μ΄κΈ°ννκ³Response DTO β StringμΌλ‘ λ³κ²½ν΄ ν΄λΌμ΄μΈνΈμκ² μ μ‘ν΄λΌμ΄μΈνΈλ μ΄λ₯Ό λ°μ νμ±νμ¬
String β Response DTOλ₯Ό μμ±ν΄ μ¬μ© -
Request DTO: ν΄λΌμ΄μΈνΈκ° μλ²μ 보λ΄λ λ©μμ§ (κ°μ²΄ λ΄μ©μ λ¬Έμμ΄λ‘ μμ±) -
Response DTO: μλ²κ° μ¬μ©μμκ² λ³΄λ΄λ λ©μμ§ (κ°μ²΄ λ΄μ©μ λ¬Έμμ΄λ‘ μμ±)-
νλ¦λ
-
νμ± λ°μ΄ν° ν μ΄λΈ
DtoType:dataνμμ λ¬Έμμ΄λ‘ λ©μμ§ μ‘μμRequestμ μ μ‘ μ£Όμ²΄λClient,Responseμ μ μ‘ μ£Όμ²΄λServer
-
DtoTypeμ λ°λΌ λ©μμ§ μ‘μμ λΆμμ λΆκΈ° μ²λ¦¬class enum DtoType { INIT, // λ‘κ·ΈμΈ ν μ΄κΈ° λ°μ΄ν° μ μ‘ κ΄λ ¨ λ©μμ§ (μ¬μ©μ 리μ€νΈ, μ±ν λ°© 리μ€νΈ) LOGIN, // λ‘κ·ΈμΈ λ©μμ§ (μ¬μ©μ μμ±, 리μ€νΈμ μΆκ°) CREATE_CHAT, // μλ‘μ΄ μ±ν λ°© μμ± λ©μμ§ ENTER_CHAT, EXIT_CHAT, // μ±ν λ°© μ μ₯, ν΄μ₯ λ©μμ§ MESSAGE, // μ±ν λ©μμ§ USER_LIST, CHAT_ROOM_LIST, // μ¬μ©μ 리μ€νΈ, μ±ν λ°© 리μ€νΈ λ©μμ§ }
class DTO { DtoType type; public DTO(DtoType type) { this.type = type; } public DtoType getType() { return type; } @Override public String toString() { return type + ":"; } }
-
μμ μ½λ
/* Client Request */ // Client Application public class LoginRequest extends DTO { String id; String name; public LoginRequest(String id, String name) { super(DtoType.LOGIN); this.id = id; this.name = name; } // λ°μ΄ν° λ³΄λΌ λ κ°μ²΄ λ΄μ©μ λ°νμΌλ‘ λ¬Έμμ΄λ‘ λ°κΏμ μ μ‘ @Override public String toString() { return super.toString() + id + "," + name; } } // Server Application public class LoginRequest { String id; String name; // μ€νΈλ§ λ©μμ§λ‘ μμ ν λ΄μ©μ κ°μ²΄λ‘ νμ±ν΄μ μ¬μ© public LoginRequest(String message) { String[] value = message.split(","); id = value[0]; name = value[1]; } public String getId() { return id; } public String getName() { return name; } }
/* Server Response */ // Server Application public class ChatRoomListResponse extends DTO { List<ChatRoom> chatRooms; public ChatRoomListResponse(List<ChatRoom> chatRooms) { super(DtoType.CHAT_ROOM_LIST); this.chatRooms = chatRooms; } // Object to String @Override public String toString() { String str = super.toString(); for (ChatRoom chatRoom : chatRooms) { str += chatRoom.getName() + ","; } return (chatRooms.size() > 0) ? str.substring(0, str.length() - 1) : str + "empty"; } } // Client Application public class ChatRoomListResponse { List<ChatRoom> chatRooms = new ArrayList<>(); // String to Object public ChatRoomListResponse(String message) { if (!message.equals("empty")) { String[] names = message.split(","); for(String name : names) { chatRooms.add(new ChatRoom(name)); } } } public List<ChatRoom> getChatRooms() { return chatRooms; } }
-
-
-
ν΄λμ€ λ©€λ²
class Application { public static List<Sockets> sockets; // ν΄λΌμ΄μΈνΈ μμΌ λ¦¬μ€νΈ ChatService chatService; // μ±ν λ°μ΄ν° μ²λ¦¬ μΈμ€ν΄μ€ (ServerThread μΈμ€ν΄μ€ μμ± μ νλΌλ―Έν°λ‘ μ λ¬) ChatDao chatDao; // μ±ν λ°μ΄ν° κ΄λ¦¬ μΈμ€ν΄μ€ (ChatService μΈμ€ν΄μ€ μμ± μ νλΌλ―Έν°λ‘ μ λ¬) } β Application μΈμ€ν΄μ€λ main ν¨μ μ€ν μ ν λ²λ§ μμ±νλ―λ‘, μ ν리μΌμ΄μ μμ μ¬μ©νλ μΈμ€ν΄μ€λ€μ μμ±ν΄μ£Όλ μν β Application μμ ν΄λΌμ΄μΈνΈλ€μ Socket μ°κ²°μ λκΈ°νλ©° ν΅μ μ μν μμΌμ μμ±νλ―λ‘ Socket List λ ν¨κ» κ΄λ¦¬ class ServerThread { Socket socket; // ν΄λΌμ΄μΈνΈ μμΌ ChatService chatService; } β κ° ν΄λΌμ΄μΈνΈλ§λ€ ServerThread μΈμ€ν΄μ€λ₯Ό μμ±νμ¬ μ€λ λλ₯Ό λμμμΌ λ©μμ§ μμ class User { String id; // μμ΄λ String name; // μ΄λ¦ Socket socket; // μμ μ μμΌ (ν΄λΌμ΄μΈνΈ μμΌ) } β μ¬μ©μ ν΄λμ€λ μμ μ μμΌ μ 보λ₯Ό μ μ₯ β μ¬μ©μ μΈμ€ν΄μ€λ₯Ό μ±ν λ°© μ¬μ©μ 리μ€νΈμ μΆκ°/μμ νλ©° λ©μμ§ μ‘μ κ΄λ¦¬ class ChatRoom { String name; // μ±ν λͺ List<User> users; // μ±ν λ°© λ΄μ μ¬μ©μ 리μ€νΈ } β μ±ν λ°© μ μ₯/ν΄μ₯μ λ°λΌ μ¬μ©μ 리μ€νΈμ User μΈμ€ν΄μ€λ₯Ό μ½μ λλ μμ β κ° μ±ν λ°©μ κ΄λ¦¬λκ³ μλ μ¬μ©μ 리μ€νΈλ₯Ό λ°νμΌλ‘ μλ²μμ λ©μμ§ μ‘μ β User μΈμ€ν΄μ€ μμ Socket μ λ³΄κ° μμΌλ―λ‘ κ°λ³μ μΈ μ±ν λ°© μ²λ¦¬κ° κ°λ₯ class ChatService { ChatDao chatDao; } β DAO μμ μ 곡νλ λ©μλλ₯Ό μ΄μ©ν΄, μ±ν νλ‘κ·Έλ¨μμ μ¬μ©νλ λ°μ΄ν°λ₯Ό κ°μ Έμμ μ²λ¦¬ class ChatDao { List<User> users; // μ μ μ€μΈ λͺ¨λ μ¬μ©μ 리μ€νΈ List<ChatRoom> chatRooms; ChatRoom lobby; // λ‘λΉ μ±ν λ°© μ 보 (λ‘λΉλ₯Ό κ³μ κ±°μ³ λ€λλ λ‘λΉ μ 보 μ μ₯) String LOBBY_CHAT_NAME = "Lobby"; } β ChatService μΈμ€ν΄μ€μμ μμ²νλ μ±ν λ°μ΄ν°λ₯Ό μ 곡 β λ€λ₯Έ μ±ν λ°©μ λ€μ΄κ° μμ΄λ λ‘λΉ μ±ν λ°©μ κ³μ κ°±μ νκΈ° μν΄ lobby λ‘ λ°λ‘ κ΄λ¦¬
-
μ ν리μΌμ΄μ ꡬ쑰
- ν΄λμ€ λ€μ΄μ΄κ·Έλ¨
-
μΈμ€ν΄μ€ λ€μ΄μ΄κ·Έλ¨
β
β
-
ν΄λμ€ λ©€λ²
class Application { public static Socket socket; public static MessageSender sender; public static MessageReceiver receiver; public static LobbyFrame lobbyFrame; public static User me; public static List<User> users = new ArrayList<>(); // νμ¬ μ μ μ€μΈ λͺ¨λ μ¬μ©μ 리μ€νΈ public static List<ChatRoom> chatRooms = new ArrayList<>(); // μ±ν λ°© νλ μ κ΄λ¦¬, λ©μμ§ μμ λ μ΄λ€ μ±ν λ°© λ μ΄λΈμ κ°±μ ν΄μΌ νλμ§ νμΈ // [key] μ±ν λ°© μ΄λ¦ public static Map<String, ChatPanel> chatPanelMap = new HashMap<>(); public static Map<String, ChatRoomUserListPanel> chatRoomUserListPanelMap = new HashMap<>(); public static final String LOBBY_CHAT_NAME = "Lobby"; // λ‘λΉ μ±ν λ°© μ΄λ¦ } β μλ²μ μμΌ μ°κ²° ν μμΌ μ 보λ₯Ό μ μ₯νκ³ κ΄λ¦¬ β μ£ΌκΈ°μ μΌλ‘ μμΌ λ©μμ§λ₯Ό μ½κΈ° μν μ€λ λ μμ± class MessageReader { Socket socket; } class MessageSender { Socekt socket; }
-
νλ©΄ νλ μ















