728x90
💬 구현 하기 전에 오늘 알아 할 내용 JSON / SET 💬
파이널 프로젝트에서 채팅구현을 하기로 해서 찾아보고 있던 중 수업시간에 운 좋게 배우게 되었다.
우선 채팅 구현을 위해서는 웹소켓이라는 것을 알아야 한다.
🤔💭[WebSocket] 웹소켓이란 ?
* 소켓 ( 양 끝단 ! 연결 시켜주는 것 )
: 클라이언트와 서버를 연결시켜 주는 것으로 서버는 모든 클라이언트의 정보를 가지고 있다.
- 브라우저와 웹서버간의 전이중통신을 지원하는 프로토콜이다
- HTML5버전부터 지원하는 기능이다.
- 자바 톰캣7버전부터 지원했으나 8버전부터 본격적으로 지원한다.
- spring4부터 웹소켓을 지원한다.
(전이중 통신(Full Duplex): 두 대의 단말기가 데이터를 송수신하기 위해
동시에 각각 독립된 회선을 사용하는 통신 방식.
대표적으로 전화망, 고속 데이터 통신)
💻 세팅하기
📚 Spring
📗 porm.xml
<!-- Spring WebSocket -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Jackson-databin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<!--Java에서 JSON을 쉽게 다룰 수 있게 해주는 구글 라이브러리 -->
<!-- GSON 라이브러리 -->
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
📗 TestWebsocketHandler.java
- extends TextWebSocketHandler 상속을 먼저 해준다.
TextWebSocketHandler
: WebSocketHandler 인터페이스를 상속받아 구현한 텍스트 메세지 전용 웹소켓 핸들러 클래스
- WebSocketHandler 주요 메소드 세팅해주기
void afterConnectionEstablished(WebSocketSession session)
- 클라이언트와 연결이 완료되고, 통신할 준비가 되면 실행
void handlerMessage(WebSocketSession session, WebSocketMessage message)
- 클라이언트로부터 메세지가 도착하면 실행
void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus)
- 클라이언트와 연결이 종료되면 실행
void handleTransportError(WebSocketSession session, Throwable exception)
- 메세지 전송중 에러가 발생하면 실행
public class TestWebsocketHandler extends TextWebSocketHandler {
// WebSocketSession : 클라이언트 - 서버 간 전이중통신을 담당하는 객체(실시간)
// 클라이언트의 세션을 가로채서 저장하고 있음
// Set 중복 x 순서 x
// synchronizedSet : 동기화된 Set 객체 반환
// -> 멀티쓰레드( 줄 안서도 기능들이 서로 실행되려고 함 )
// 멀티쓰레드 환경에서 스레드간의 의도치 않은 충돌을 예방하기 위해서 동기화(줄세움)
private Set<WebSocketSession> sessions
= Collections.synchronizedSet(new HashSet<>());
// - 클라이언트와 연결이 완료되고, 통신할 준비가 되면 실행
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 클라이언트 웹 소켓 연결을 요청하면 sessions에
// 클라이언트와의 전이중 통신을 담당하는 객체 WebSocketSession을 추가
// WebSocketSession session : 클라이언트에게 가로챈 세션!
sessions.add(session);
}
// - 클라이언트로부터 텍스트 메세지를 받았을때 실행
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// Payload : 통신 시 탑재된 데이터(메세지)
System.out.println("전달받은내용:"+message.getPayload());
// /testSock/으로 연결된 객체를 만든 클라이언트들(sessions)
// 전달 받은 내용을 보냄
for(WebSocketSession s : sessions) {
s.sendMessage(message);
}
}
// - 클라이언트와 연결이 종료되면 실행
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// sessions에서 나간 클라이언트의 정보를 제거
sessions.remove(session);
}
}
❗ 코드 해석
1. extends TextWebSocketHandler 상속 받기
2. private Set<WebSocketSession> sessions = Collections.synchronizedSet(new HashSet<>());
- Set : 중복 x 순서 x
- WebSocketSession : 클라이언트 세션을 가로채서 저장하고 있음
- synchronizedSet : 동기화된 Set 객체 반환
현재 멀티쓰레드 환경에서 스레드간의 의도치 않은 충돌을 예방하기 위해서 동기화
🤔 멀티쓰레드 : 기능이 줄을 서지 않고 너도 나도 서로 실행되려고 하는 상태!
3. WebSocketHandler 주요 메소드 세팅하기
- afterConnectionEstablished : 클라이언트에게 가로책 세션을 넣어주기!
- handleTextMessage : 클라이언트에게 받은 텍스트 실행
- afterConnectionClosed : sessions에서 나간 클라이언트의 정보를 제거해주기 !
- servlet-context.xml 세팅하기
<!-- 웹소켓 처리 클래스를 bean으로 등록 -->
<beans:bean id="testHandler"
class="edu.kh.project.main.model.websocket.TestWebsocketHandler"/>
<!-- 어떤 주소로 웹소켓 요청이 오면 세션을 가로챌지 지정 -->
<websocket:handlers>
<websocket:mapping handler="testHandler" path="/testSock/"/>
<!-- 요청 클라이언트의 세션을 가로채서 WebSocketSession에 넣어주는 역할 -->
<websocket:handshake-interceptors>
<beans:bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
</websocket:handshake-interceptors>
<!-- SockJS를 이용한 웹소켓연결 요청임을 명시 -->
<websocket:sockjs/>
</websocket:handlers>
📚 Spring
📕 main.jsp
<%-- footer --%>
<jsp:include page="/WEB-INF/views/common/footer.jsp" />
<%-- SockJS 추가 --%>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<%-- main.js 추가 --%>
<script src="/resources/js/main.js"></script>
📕 main.js
// 웹소켓 테스트
// 1. SockJS라이브러리 추가 -> main.jsp 추가
//2. SockJS를 이용해서 클라리언트용 웹소켓 객체 생성
let testSock = new SockJS("/testSock/");
function sendMessage(name,str){
//매개변수 JS객체에 저장
let obj = {}; // 비어있는 객체
obj.name = name; // 객체에 일치하는 key가 없다면 자동으로 추가
obj.str = str;
//console.log(obj);
// 웹 소켓 연결된 곳으로 메세지를 보냄
testSock.send(JSON.stringify(obj));
// JS객체 -> JSON으로 보냄!
}
// 웹소켓 객체(testSock)가 서버로 부터 전달 받은 메세지가 있을경우
testSock.onmessage = e => {
// e: 이벤트 객체
// onmessage: 이벤트가 오는걸 감지
// e.data : 전달 받은 메세지(JSON)
let obj = JSON.parse(e.data); // JSON -> JS객체
console.log(`보낸사람 : ${obj.name} / ${obj.str}`);
}
❗ 코드 해석
servlet-context.xml에 웹소켓 요청이 오면 세선을 가로챌지 결정한 부분에서
path ="/testSock/"이라고 명칭을 지었다.
SockJS 을 이용해서 웹소켓 객체를 생성하고, 연결된 곳으로 JS객체를 JSON으로 보낸다 !
그 뒤 전달 받은 메세지가 있다면 JS객체로 parse해서 출력하게 해준다.
🔮 console 출력화면
어떤 식으로 설정할지와 이론을 확인해봤으니 이제 실전으로 직접 체팅방 구현을 해보자
[ Spring ] 채팅 구현하기 - 실전편 ②
이전 시간에 채팅 구현하기 앞서 어떻게 세팅해야할지 어떤 식으로 돌아가는지 콘솔을 통해 알아보았다. 오늘은 직접 채팅을 구현해보자! 🔮 출력 화면 미리보기 체팅 기능을 실행하기 위한 DB
jnaa.tistory.com
728x90
'ON > spring' 카테고리의 다른 글
[ Spring ] 채팅 구현하기 - 실전편 ③ (0) | 2023.09.04 |
---|---|
[ Spring ] 채팅 구현하기 - 실전편 ② (화면 구현 DB설정) (0) | 2023.09.04 |
[ Spring ] SpringAOP 사용하기 ⑳ (0) | 2023.09.02 |
[ Spring ] SpringAOP 이론 ⑱ (0) | 2023.09.01 |
[ Spring ] @Scheduled 이용하기 ⑰ (0) | 2023.09.01 |