==> 리소스도 낭비, 실시간데이터를 주고받는것도 힘들다(채팅,주식,게임,...)




웹소켓컨테이너를 활성화시키는 작업 - 웹소켓을 사용하겠다고 정의
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
@Controller
public class WebSocketController {
@GetMapping("/chat")
public String showview(){
return "chat";
}
}
웹소켓통신을 하면서 서버역할을 하는 프로그램
@Component
@ServerEndpoint(value = "/chat")
public class WebSocketBasicHandler {
//세션을 저장하기 위해서 컬렉션을 추가
//동기화된 컬렉션 - 멀티스레드환경에서 안전하게 작업할 수 있도록 제공되는 set
private static Set<Session> clientlist = Collections.synchronizedSet(new HashSet<>());
//클라이언트가 접속을하면 실행되는 메소드
@OnOpen
public void open(Session client){
System.out.println("클라이언트가 접속했다");
System.out.println(client);
if (!clientlist.contains(client)){
clientlist.add(client);
}
}
//클라이언트에게 메시지를 받으면 호출되는 메소드
//통신할때 메시지를 받으면 호출되는 메소드로 모든 접속자들한테 메시지를 전송할 수 있어야 한다.
//메시지를 받을때마다 호출되는 메소드
//텍스트메시지통신(웹소켓에 접속한 모든 클라이언트에게 메시지를 전송)
@OnMessage
public void onMessage(String msg,Session sender) throws IOException {
//웹소켓에 접속한 모든 클라이언트에게 메시지전송
System.out.println("수신된 메시지:"+msg);
System.out.println("클라이언트:"+sender);
for(Session client:clientlist){
client.getBasicRemote().sendText(msg);
}
}
@OnClose
//접속종료 - 소켓연결이 끊어지면 호출되는 메소드
public void onClose(Session client){
System.out.println("접속종료");
clientlist.remove(client);
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style type="text/css">
#talklist{
border:1px solid;
width: 600px;
height: 400px
}
#msg{
border:1px solid;
width: 550px;
margin-top: 10px
}
#sendbtn{
height: 40px;
margin-top: 10px;
}
#id{
width: 350px;
margin-bottom: 10px
}
.me{
background-color: #FAECC5;
width: 70%;
float: right;
margin: 1px
}
.other{
background-color: #EAEAEA;
width: 70%;
float: left;
margin: 1px
}
</style>
</head>
<body>
<div id='chatt'>
<h1>웹 소켓 채팅</h1>
<input type='text' id='id' >
<input type='button' value='채팅참여' id='joinbtn' >
<input type='button' value='채팅종료' id='btnclose' >
<br/>
<div id='talklist'></div>
<div id='sendZone'>
<textarea id='msg' ></textarea>
<input type='button' value='전송' id='sendbtn'>
</div>
</div>
<script type="text/javascript">
//전송할 데이터가 여러개이므로 json으로 전송
let mydata = {};
$(document).ready(function(){
$("#joinbtn").on("click",function(){
//alert(location.host);
//1. 웹소켓객체를 생성 - 서버에 연결하는 작업
ws = new WebSocket("ws://"+location.host+"/chat");
//연결이 되면 이벤트에 반응할 수 있도록 콜백등록
//웹소켓에서 클라이언트로 전송하는 메시지를 받을 수 있도록 처리
//웹소켓에 연결된 후에 실행
ws.onopen = function(msg){
console.log(msg);
$("#talklist").append("<div>접속완료....</div>");
}
//웹소켓 연결 후에 서버가 메시지를 보내면 받을 수 있도록 콜백등록
ws.onmessage = function(msg){
//실제 데이터가 json으로 전송
console.log(msg.data);
//받은 메시지를 출력 - 내가 보낸건지 받은 메시지인지 확인하기 위해서 id하고 비교
//전송되는 메시지에서 데이터만 추출
//json데이터에 저장된 값을 엑세스하려면 JSON문자열을 parsing해야한다.
let resMsg = JSON.parse(msg.data);
console.log(resMsg);
let msgcss = "";
if(resMsg.id==$("#id").val()){//내가 작성한 메시지인지 확인
msgcss = "class = me";
}else{
msgcss = "class = other";
}
//talklist에 출력할 div생성
let item = "<div "+ msgcss+ " ><span><b>"+ resMsg.id+ "</b></span>"
+ "<b>["+ resMsg.date+ "]</b><br/>"
+ "<span>"+ resMsg.msg +"</span>"
+"</div>"
$("#talklist").append(item);
}
//웹소켓이 종료된 후에 발생하는 이벤트에 대해서 처리할 수 있도록 콜백등록
ws.onclose = function(msg){
//실제 데이터가 json으로 전송
console.log(msg);
$("#talklist").append("<div>접속종료....</div>");
}
ws.onerror = function(msg){
//실제 데이터가 json으로 전송
console.log(msg);
$("#talklist").append("<div>에러발생....</div>");
}
});
$("#sendbtn").on("click",function(){
sendMessage();
})
$("#msg").on("click",function(event){
//엔터키가 눌려지면
if(event.keyCode==13){
sendMessage();
}
})
$("#btnclose").on("click",function(){
//웹소켓연결종료
ws.close();
})
})
function sendMessage(){
//메시지전송함수
//서버로 보낼 메시지를 만들어서 전송
//지금은 id를 <input>에서 꺼내지만 나중에는 웹의 세션에 저장된 dto에서 꺼내기
mydata.id = $("#id").val();
mydata.msg = $("#msg").val();
mydata.date = new Date().toLocaleDateString();//오늘날짜
mydata.type = "textmsg";//메시지유형(텍스트와 바이너리를 구분하기 위한 값)
//자바스크립트 객체로 정의된 데이터를 json문자열로 변환
let sendMsg = JSON.stringify(mydata);
ws.send(sendMsg);//웹소켓서버로 메시지를 전송
$("#msg").val("");//메시지전송이 완료되면 텍스트창을 지우기
}
</script>
</body>
</html>

본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.