[Spring4] 스프링 웹소켓(WebSocket) 예제
스프링 웹소켓 예제를 구현해보았다.
검색해보니 구현방법이 무척 많았는데, 최대한 쉽게 구현된 형태를 참고하였다.
명월일지라는 블로그의 http://nowonbun.tistory.com/285 라는 포스트를 주로 참고하였다.
간단하게 다중 채팅방을 구현해보았다.
1. 스프링 웹 프로젝트 생성
먼저 스프링 웹 프로젝트가 필요하다.
기존에 있으면 건너뛰어도 된다. 기존에 없으면 아래 포스트를 참고해서 만들면 된다.
=> [Spring4] STS에서 스프링 웹 프로젝트 생성 (https://blog.naver.com/bb_/221339454799)
2. pom.xml 수정
WebSocket Server API 라는 라이브러리가 필요하다.
pom.xml 에 다음 코드를 추가하였다.
|
<dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency>
|
따로 다운받고 싶으면 MVN Repository를 방문하면 된다. https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api 에서 1.1 버전 다운받으면 된다.
3. Websocket.java 파일 작성
적당한 위치에 Websocket.java 파일을 만들고 아래처럼 코드를 작성한다.
|
// 패키지 위치는 자유롭게 결정
package com.bb.vivria.socket;
import java.util.ArrayList;
import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(“/websocket”) public class Websocket {
/** * 웹소켓 세션을 담는 ArrayList */ private static ArrayList<Session> sessionList = new ArrayList<Session>();
/** * 웹소켓 사용자 연결 성립하는 경우 호출 */ @OnOpen public void handleOpen(Session session) { if (session != null) { String sessionId = session.getId(); System.out.println(“client is connected. sessionId == [“ + sessionId + “]”); sessionList.add(session); // 웹소켓 연결 성립되어 있는 모든 사용자에게 메시지 전송 sendMessageToAll(“***** [USER-“ + sessionId + “] is connected. *****”); } }
/** * 웹소켓 메시지(From Client) 수신하는 경우 호출 */ @OnMessage public String handleMessage(String message, Session session) { if (session != null) { String sessionId = session.getId(); System.out.println(“message is arrived. sessionId == [“ + sessionId + “] / message == [“ + message + “]”);
// 웹소켓 연결 성립되어 있는 모든 사용자에게 메시지 전송 sendMessageToAll(“[USER-“ + sessionId + “] “ + message); }
return null; }
/** * 웹소켓 사용자 연결 해제하는 경우 호출 */ @OnClose public void handleClose(Session session) { if (session != null) { String sessionId = session.getId(); System.out.println(“client is disconnected. sessionId == [“ + sessionId + “]”); // 웹소켓 연결 성립되어 있는 모든 사용자에게 메시지 전송 sendMessageToAll(“***** [USER-“ + sessionId + “] is disconnected. *****”); } }
/** * 웹소켓 에러 발생하는 경우 호출 */ @OnError public void handleError(Throwable t) { t.printStackTrace(); } /** * 웹소켓 연결 성립되어 있는 모든 사용자에게 메시지 전송 */ private boolean sendMessageToAll(String message) { if (sessionList == null) { return false; }
int sessionCount = sessionList.size(); if (sessionCount < 1) { return false; }
Session singleSession = null;
for (int i = 0; i < sessionCount; i++) { singleSession = sessionList.get(i); if (singleSession == null) { continue; }
if (!singleSession.isOpen()) { continue; }
sessionList.get(i).getAsyncRemote().sendText(message); }
return true; } }
|
4. test.jsp 파일 작성
적당한 위치에 test.jsp 파일을 만들고 아래처럼 코드를 작성한다.
여기서는 webapp/WEB-INF/chat/test.jsp 에 위치한다고 가정한다.
|
<%@ page contentType=“text/html; charset=utf-8” %> <!DOCTYPE html> <html> <head> <meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”> <title>웹소켓 테스트 페이지</title> <script type=“text/javascript”> var g_webSocket = null; window.onload = function() { g_webSocket = new WebSocket(“ws://localhost:8080/websocket”); /** * 웹소켓 사용자 연결 성립하는 경우 호출 */ g_webSocket.onopen = function(message) { addLineToChatBox(“Server is connected.”); }; /** * 웹소켓 메시지(From Server) 수신하는 경우 호출 */ g_webSocket.onmessage = function(message) { addLineToChatBox(message.data); };
/** * 웹소켓 사용자 연결 해제하는 경우 호출 */ g_webSocket.onclose = function(message) { addLineToChatBox(“Server is disconnected.”); };
/** * 웹소켓 에러 발생하는 경우 호출 */ g_webSocket.onerror = function(message) { addLineToChatBox(“Error!”); }; }
/** * 채팅 박스영역에 내용 한 줄 추가 */ function addLineToChatBox(_line) { if (_line == null) { _line = “”; } var chatBoxArea = document.getElementById(“chatBoxArea”); chatBoxArea.value += _line + “\n”; chatBoxArea.scrollTop = chatBoxArea.scrollHeight; }
/** * Send 버튼 클릭하는 경우 호출 (서버로 메시지 전송) */ function sendButton_onclick() { var inputMsgBox = document.getElementById(“inputMsgBox”); if (inputMsgBox == null || inputMsgBox.value == null || inputMsgBox.value.length == 0) { return false; } var chatBoxArea = document.getElementById(“chatBoxArea”); if (g_webSocket == null || g_webSocket.readyState == 3) { chatBoxArea.value += “Server is disconnected.\n”; return false; } // 서버로 메시지 전송 g_webSocket.send(inputMsgBox.value); inputMsgBox.value = “”; inputMsgBox.focus(); return true; }
/** * Disconnect 버튼 클릭하는 경우 호출 */ function disconnectButton_onclick() { if (g_webSocket != null) { g_webSocket.close(); } }
/** * inputMsgBox 키입력하는 경우 호출 */ function inputMsgBox_onkeypress() { if (event == null) { return false; } // 엔터키 누를 경우 서버로 메시지 전송 var keyCode = event.keyCode || event.which; if (keyCode == 13) { sendButton_onclick(); } } </script> </head> <body> <input id=“inputMsgBox” style=“width: 250px;” type=“text” onkeypress=“inputMsgBox_onkeypress()”> <input id=“sendButton” value=“Send” type=“button” onclick=“sendButton_onclick()”> <input id=“disconnectButton” value=“Disconnect” type=“button” onclick=“disconnectButton_onclick()”> <br/> <textarea id=“chatBoxArea” style=“width: 100%;” rows=“10” cols=“50” readonly=“readonly”></textarea> </body> </html>
|
5. ChatController.java 파일 작성
도메인:포트/chat 으로 접속하면 test.jsp 에 도달할 수 있도록 ChatController.java 파일을 작성한다.
패키지 위치는 자유롭게 결정하면 된다.
예를 들어 localhost:8080/chat 으로 접속했을 때 test.jsp 가 뜨면 성공이다.
|
// 패키지 위치는 자유롭게 결정
package com.bb.vivria.controller;
import java.util.Locale;
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;
@Controller public class ChatController { @RequestMapping(value = “/chat”, method = RequestMethod.GET) public String home(Locale locale, Model model) { return “chat/test”; } }
|
5. 테스트
브라우저 여러 개를 띄워, 도메인:포트/chat (예를 들어 localhost:8080/chat) 에 접속한 후 채팅을 해보자.
잘되면 성공이다.

이상 스프링 웹소켓(WebSocket) 예제를 마친다.