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; }
-
ํ๋ฉด ํ๋ ์