초간단 WebSocket 채팅
spring websocket pom.xml에 추가
websocket-context.xml 추가
namespace에 websocket 추가
- End Point : 고정된 url에 서비스하는것
- 채팅을 하게되면 모든 사람들이 특정 url에 접속을 하게됌
- 그 url을 end point라고 함
TextWebSocketHandler를 extends 받은 클래스 생성
websocket-context.xml에 handler 빈등록
Controller에 url주고 jsp생성
pom.xml
<!-- 웹소켓 실시간 알림등 구현에 필요-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="<http://www.springframework.org/schema/beans>"
xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
xmlns:websocket="<http://www.springframework.org/schema/websocket>"
xsi:schemaLocation="<http://www.springframework.org/schema/websocket> <http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd>
<http://www.springframework.org/schema/beans> <http://www.springframework.org/schema/beans/spring-beans.xsd>">
<!--
End Point를 이해, 여기서는 고정 URL : /ws-chat을 의미
webSocket은 양방향 프로토콜, http는 단방향 프로토콜
ws -> http를 기반으로 만들어졌고
wss -> https를 기반으로 만들어졌다.
-->
<bean id="chatHandler" class="com.mijung.sample.listener.DongSukChat"></bean>
<websocket:handlers allowed-origins="*">
<websocket:mapping handler="chatHandler" path="/ws-chat" />
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
</beans>
handler
package com.mijung.sample.listener;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DongSukChat extends TextWebSocketHandler{
//접속한 웹소켓 세션을 저장
private static List<WebSocketSession> list = new ArrayList<WebSocketSession>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.debug("연결 성공");
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
log.debug("메세지 도착");
log.debug("내용 : "+message.getPayload());
String uMsg = message.getPayload();
for (WebSocketSession webSocketSession : list) {
webSocketSession.sendMessage(message);
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.debug("연결 종료");
list.remove(session);
}
}
controller
package com.mijung.sample;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@GetMapping("/letschat")
public String letsChat() {
return "chat";
}
}
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>초간단 채팅</title>
<style>
#id_chatwin {
width:300px;
height:300px;
background-color:black;
border:1px solid pink;
color:yellow;
}
</style>
</head>
<body>
<h1>간단히 대화라도 할깡</h1>
<div>
<div id="id_chatwin"></div>
<input type="text" id="id_message" />
<input type="button" id="id_send" value="전송">
<input type="button" id="id_exit" value="퇴장">
</div>
</body>
<script>
const c_alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const f_ranID=()=>{
let ranID ="";
for(let i=1; i< (Math.ceil(Math.random()*5)+4); i++){
ranID += c_alpha[Math.floor(Math.random()*c_alpha.length)];
}
return ranID;
}
let webSocket;
let myId = f_ranID();
const c_chatWin = document.querySelector("#id_chatwin");
const c_message = document.querySelector("#id_message");
const c_send = document.querySelector("#id_send");
const c_exit = document.querySelector("#id_exit");
c_send.addEventListener("click", ()=>{
send();
});
// 연결 끊깅
c_exit.addEventListener("click", function () {
disconnect();
});
//연결
connect();
function connect() {
webSocket = new WebSocket("ws://localhost:8004/sample/ws-chat"); // End Point
//이벤트에 이벤트핸들러 뜽록
webSocket.onopen = onOpen;
webSocket.onmessage = onMessage;
}
//연결 시
function onOpen() {
webSocket.send(myId + "님 입장.");
}
function send() {
let msg = c_message.value;
webSocket.send(myId + ":" + msg);
c_message.value = "";
}
function onMessage() {
let data = event.data;
c_chatWin.innerHTML = c_chatWin.innerHTML + "<br/>" + data;
}
function disconnect() {
webSocket.send(myId + "님이 퇴장");
webSocket.close();
}
</script>
</body>
</html>