http는 클라이언트가요청을 해야 응답을 해주는 polling 방식임
요청이 없어도 응답을 해주는 push방식(실시간으로 데이터 주고받기)

필요해서 나온게  요놈임
주기적으로 걍 계속 서버에 요청하는 것 보단 낫다고 함

 

프로토콜 형태는 ws://~~

서버부하, 보안(Security)적인 측면과 세션 관리 등의 문제를 가지고 있고
가장 큰 단점으로는  구 브라우저(IE 8.0)에서는 작동하지 않는 문제점이 있다 

고는 하지만 요새 누가 구 버전을 쓰나

 

서버연결
=> WebSocket 객체를 통해 서버 연결
=>기본 포트 역시 http,https와 동일한 80,443을 이용
데이터 송신
=>end 함수로 데이터를 서버로 송신
데이터 수신
=>푸시(전송)하는 데이터를 받으려면 message 이벤트를 구현

채팅구현! 올 실제코드 가보자

 

항..... 수업시간에 적어놓은 메모장 다 날아가서 기억으로 더듬더듬 작성해야해.... 헝...그래도 뭔가 xml에 라이브러리 등록은 해야하니까 pom.xml에가서 라이브러리 등록 !

<!-- 웹 소켓용 라이브러리 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

 

그리고 자바코드로 등록을 해야 겠지

WebSocketConfig.java

@Configuration
@EnableWebSocket  //서블릿컨텍스트에다가 빈으로 설정한 것과 같음!!
public class WebSocketConfig implements WebSocketConfigurer{
	//웹 소켓 서버를 생성자 인젝션으로 초기화  - 아래 ~메소드에서 사용해야해서..?
	private final WebSocketServer webSocketServer;
	public WebSocketConfig(WebSocketServer webSocketServer) {
		this.webSocketServer=webSocketServer;
	}
	
	//클라이언트 접속을 위한 엔드포인트 설정
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		registry.addHandler(webSocketServer, "/chat-ws.do").setAllowedOrigins("*");		
	}		
}

 

그리고 나서 웹소켓 서버를 설정 했던 것 같음

WebSocketServer.java

//웹 소켓 서버
@Component
public class WebSocketServer extends TextWebSocketHandler {
	
	//접속한 클라이언트를 저장하기 위한 속성(멤버변수)
	//키는 웹소켓 세션 아니디
	private Map<String,WebSocketSession> clients = new HashMap<>();

	//클라이언트와 연결 되었을 때 호출되는 콜백 메소드
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		//컬렉션에 연결된 클라이언트 추가
		clients.put(session.getId(), session);
		System.out.println(session.getId()+"연결 되었습니다.");
	}/////////

	//클라이언트로부터 메시지를 받았을 때 호출되는 메소드
	//여기서 클라이언트로 메시지도 보냄
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		System.out.println(session.getId()+"로부터 받은 메시지"+message.getPayload());
		//접속한 모든 클라이언트에게 session.getId()가 보낸 메시지 뿌리기
		for(WebSocketSession client:clients.values()) {  
			if(!session.getId().equals(client.getId())) {  //자기가 보낸 메시지를 자기한테 다시 받지 않도록
				//받은 메시지를 그대로 접속한 모든 인원에게 push
				client.sendMessage(message);
			}
		}
	}///////////////

	//통신 장애 시 자동으로 호출되는 메소드
	@Override
	public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
		 System.out.println(session.getId()+"와 통신장애 발생:"+e.getMessage());
	}///////

	//클라이언트와 연결 끊어졌을 때 호출되는 메소드
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		//컬렉션 저장 된 클라이언트 삭제
		clients.remove(session.getId());
		System.out.println(session.getId()+"연결이 끊어졌습니다.");		
	}/////////
		
}////////////////

근데 서버 잘 작동시키려면

방화벽 설정? 해줘야함 

방화벽이 걍 다 막아버린댜

검색창에 방화벽 치면

요거 클릭

요리 설정

저거 다음 포트는 8080 넣어주

나머지는 쭉쭉

다음 누르다가 마지막

하면 서버설정 끝 !!!

 

그리고 뷰!!! 는 거의 가져오고

그 밑의 자바코드를 잘 보자!

//얜 그냥 뷰 .. 넘어가도 됨
 <style>
	p {
	  color: whitesmoke;
	  margin: 10px;
	}
	
	span {
	  display: inline-block;
	  max-width: 180px;
	  padding: 5px 10px;
	  position: relative;
	  word-wrap: break;
	}
	
	.ext {
	  text-align: left;
	}
	
	.ext span {
	  background: #000000;
	  border-radius: 0 5px 5px 5px;
	}
	
	.int {
	  text-align: right;
	}
	
	.int span {
	  background: #ff0000;
	  border-radius: 5px 5px 0 5px;
	  right: 0;
	}
</style>
 
<div class="container">     
	<fieldset class=" form-group border p-3">
		<legend class="w-auto px-3">웹소켓</legend>
		
		<form>
		<div class="form-group">
			<label><kbd class="lead">닉네임</kbd></label> 
			<input type="text" class="form-control" id="nickname" 
			placeholder="닉네임을 입력하세요">
		</div>
		<input class="btn btn-info" type="button" id="enterBtn" value="입장">
		<input class="btn btn-danger" type="button" id="exitBtn" value="퇴장">


		<div class="form-group">
			<h4>대화내용</h4>
			<div id="chatArea">
				<div id="chatMessage"  
					style="height: 300px; border: 1px gray solid; overflow:auto;"></div>
			</div>
		</div>

		<div class="form-group">
			<label><kbd class="lead">메시지</kbd></label> 
			<input type="text" class="form-control" id="message" placeholder="메시지를 입력하세요">
		</div>		
	</form>
			
	</fieldset>	
</div>  
  <jsp:include page="/WEB-INF/views/template/Footer.jsp" />

요 밑에 진짜 중요한 스크립트 코드 !!!!!!!

 

채팅 테스트
localhost를 아이피로 변경(192.168.219.137  =>요건 내 아이피) 소스 및 브라우저 URL도 변경
그리고 인바운드 규칙추가 8080

채팅 말풍선
https://codepen.io/beumsk/pen/mmEzrE    =>나중에  들어가 봐야지

<script>
//웹소켓 객체 저장용
var wsocket;
//닉 네임 저장용
var nickname;
//입장버튼 클릭 시 -서버와 연결된 웹소켓 클라이언트 생성
$('#enterBtn').one('click',function(){  //one 한 번만 입장해야 하니까
    wsocket = new WebSocket("ws://192.168.219.137:8080<c:url value="/chat-ws.do"/>"); //wss 는 보안이 강화된것 얘는 443포트를 사용
    console.log('wsocket:',wsocket);
    //서버와 연결된 웹 소켓에 이벤트 등록(함수들은 밑으로 다 빼놓음)
    wsocket.onopen = open;  //   open()들어가면 호출하는거여
    wsocket.onclose=function(){
        appendMessage("연결이 끊어 졌어요");
    };
    wsocket.onmessage=receive;
    wsocket.onerror=function(e){
        console.log('에러발생:',e)
    }
});
//서버에 연결되었을 때 호출되는 콜백함수
function open(){
    //서버로 연결한 사람의 정보(닉네임) 전송
    //msg:kim가(이) 입장했어요  <---이건 걍 내맘대로 만드는 규칙임
    //사용자가 입력한 닉네임 저장
    nickname = $('#nickname').val();
    wsocket.send('msg:'+nickname+'가(이) 입장했어요');
    appendMessage("연결이 되었어요");
}
//서버에서 메시지를 받을 때마다 호출되는 함수 
function receive(e){//e는 message이벤트 객체
    //서버로부터 받은 데이타는 이벤트객체(e).data속성에 저장되어 있다
    console.log('서버로부터받은 메시지:',e.data);
    if(e.data.substring(0, 4) ==='msg:')

        appendMessage("<p class='int'><span>"+e.data.substring(4)+"</span></p>");//서버로부터 받은 메시지를 msg:부분을 제외하고 div에 출력
}
function appendMessage(msg){  //이건 여러군데 사용해서 메소드로 뺀거
    //$('#chatMessage').append(msg+"<br/>");

    $('#chatMessage').append(msg);
    $('#chatMessage').get(0).scrollTop = $('#chatMessage').get(0).scrollHeight; 
    //get(0)이거 자바스크립트로 바꾸는거였지...scrollTop랑 .scrollHeight는 스크롤바를계속 올리는 공식임 
}

$('#message').on('keypress',function(e){
    console.log('keypress이벤트 발생:',e.keyCode);
    if(e.keyCode===13){//엔터 입력
        //서버로 메시지 전송
        wsocket.send('msg:'+nickname+'>>' +$(this).val());//msg:KOSMO>>안녕
        //DIV(대화영역)에 메시지 출력

        appendMessage("<p class='ext'><span>"+$(this).val()+"</span></p>");
        //기존 메시지 클리어		
        $(this).val("");
        //포커스 주기
        $(this).focus();
        $('#chatMessage').get(0).scrollTop = $('#chatMessage').get(0).scrollHeight;			
    }		
})

//퇴장버튼 클릭 시
$('#exitBtn').one('click',function(){
    wsocket.send('msg:'+nickname+'가(이) 퇴장했어요');
    wsocket.close();
});

</script>

 

오 신기

 

근데 코드분석은 좀 더 곱씹고 곱씹고 곱씹어야 겠다

눈에 안들어옴...

 

'학원 > SPRING' 카테고리의 다른 글

12/29 72-3 [SPRING] Security_1  (0) 2022.12.29
12/29 72-2 [SPRING] Tiles  (0) 2022.12.29
12/28 71-2 [SPRING] AOP(수정 )  (1) 2022.12.28
12/28 71-1 [SPRING] Upload(에러잡기)/Download  (0) 2022.12.28
12/22 70-3 [SPRING] FileUpload  (0) 2022.12.22

+ Recent posts