Java

Java, 채팅하기(Chat)

greenyellow-s 2024. 8. 16. 09:17
Chat

 

챗팅은 스레드가 필요하다.
한쪽이 처리하고 그 다음이 처리하는게 아니라(절차식) 왔다 갔다 하며 처리하는 기능이 필요하다.

 


서버는 한대이지만 chatServer는 절대 스레드가 되면 안되고

ChatServer가 중심으로 서버 소켓을 가지고 있다.

1. ChatClient가 소켓을 가지고 들어온다
2. ChatServer가 낙아챈다
3. Socket을 만들고(ChaThandle에) 뭔가가 오면 모든 ChaThandler가 ChatClient에게 다 뿌려준다.

** 하지만 소켓은 1:1로 연결되어있다.

 


 

클라이언트의 연결 요청을 수락
ServerSocket serverSocket; 

 

100개의 클라이언트가 동시에 채팅할 수 있도록
ExecutorService threadPool = Executors.newFixedThreadPool(100); 

 

통신용 ChatHandler를 관리하는 동기화된 Map 컬렉션
Map<String, ChatHandler> chatRoom = Collections.synchronizedMap(new HashMap<>());
//apple@192.168.0.42 ==> key
//chatHandler(소켓, IO_)

 

연결 수락하고, 통신용 SocketHandler를 반복해서 생성
Socket socket = serverSocket.accept();

accept() 멈춰있다



클라이언트가 들어오면 낚아채고 소켓을 만들어준다. 그리고 Handler에게 준다

Client가 들어올때마다 Handler도 계속 새로 만들어준다

chatRoom에 있는 모든 chatHandler를 닫는다
chatRoom.values()로 collection<ChatHandler>를 얻고, 요소 스틍림을 이용해서 전체 chatHandler의 close()를 호출

 


server는 자신에게 몇명의 클라이언트가 왔는지 알아야한다.


Map<String, ChatHandler> chatRoom
map은 키와 값이 세트로 들온다.
키 = apple@196.88~~~
값(values) = chatHandler -> socket + io(입출력)

클라이언트 수만큼 handler가 생성되는데 그 개수를 알게 해주는게 map이다.
chatRoom.get(apple@~~~)

map에서는 클라이언트가 사라지면 Handler도 없어져야된다.


chatRoom.values().stream().forEach(sc -> sc.close());
chatRoom에서 values -> handler
chatHandler를 close해라
chatHandler에는 close없어서 메소드 create

stream으로 for문을 돌려서 close로 간다.


JSON

 

JSON 데이터 형식
=> *.jar 필요
   https://mvnrepository.com/
   json-20231013.jar 


=> 네트워크로 전달하는 데이터가 복잡할수록 구조화된 형식이 필요하다.
   네트워크 통신에서 가장 많이 사용되는 데이터 형식은 JSON(JavaScript Object Notation)이다.
   
[형식]
① JSON 객체
{
   "속성명" : 값,
   "속성명" : 값
}   

② JSON 배열
[
   "문자열" or
   { ......} or
   [ ......]
]


ChatServer의 sendToAll() 호출하고 싶다.
그래야 모든 클라이언트에게 보낼 수 있으니까
chatHandler-send()애서 server를 또 new하면 안되고
new시킨 주소를 받아야한다.

ChatHandler chatHandler = new ChatHandler(this, socket);
this, 서버의 주소를 받아야한다.
public ChatHandler(ChatServer chatServer, Socket socket) {
서버의 주소, 소켓 두개를 받아온것이다.