Spring

[Spring] WebSocket์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ๊ตฌํ˜„ํ•˜๊ธฐ

developer of the night sky 2023. 12. 5. 20:34

ChatTestProject๐Ÿ”Ž

์•ž์„œ ์ •๋ฆฌํ•œ WebSocket์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์„ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ด๋‹ค.

๋‹‰๋„ค์ž„์„ ์„ค์ •ํ•˜์—ฌ ๋“ค์–ด๊ฐ„ ํ›„ n๋ช…๊ณผ ๋Œ€ํ™”๋ฅผ ํ•œ๋‹ค.

https://steady-record.tistory.com/entry/WebSocket

 

[Spring] WebSocket ๊ธฐ์ดˆ ์˜ˆ์ œ

Socket? WebSocket?๐Ÿ”Ž - Socket Socket๋Š” ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์œ„ํ•œ ๋„๊ตฌ๋กœ, ๋ฌด์ „๊ธฐ๋‚˜ ์ „ํ™”๊ธฐ์™€ ๊ฐ™์ด ํ”„๋กœ๊ทธ๋žจ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ์ด๋Š” ํŠน์ •ํ•œ ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํ†ต์‹  ๊ทœ๊ฒฉ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

steady-record.tistory.com

 

๊ตฌํ˜„๋œ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ….gif

 


ํŒŒ์ผ๊ตฌ์„ฑ๐Ÿ”Ž

์ƒ์œ„ ํŒจํ‚ค์ง€(ํด๋”) ํ•˜์œ„ ํŒจํ‚ค์ง€(ํด๋”) ํŒŒ์ผ๋ช… ์—ญํ• 
src/main/java com.test.controller ChatController.java ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๋ฌผ์งˆ์  ์—ฐ๊ฒฐ
  com.test.server ChatServer.java ์„œ๋ฒ„
  com.test.domain Message.java ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ด๋Š” DTO
webapp/WEB-INF/views   index.jsp ์ฑ„ํŒ… ์ž…์žฅ ์ „ ํŽ˜์ด์ง€
    chat.jsp ์ฑ„ํŒ… ํŽ˜์ด์ง€

 


ํ™˜๊ฒฝ์„ค์ •๐Ÿ”Ž

์ด ํ”„๋กœ์ ํŠธ์—์„œ๋Š” DB์ž‘์—…์„ ํ•˜์ง€ ์•Š๊ธฐ์— ๋ฒ„์ „ ๋ณ€๊ฒฝ ๋ฐ ์˜์กด์„ฑ ์ถ”๊ฐ€๋งŒ ์„ค์ •ํ•˜๊ฒ ๋‹ค.

 

1. ๋ฒ„์ „ ์„ค์ • - pom.xml

์•„๋ž˜ ๊ธ€์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ž๋ฐ”์™€ ์Šคํ”„๋ง ๋ฒ„์ „์„ ๋ณ€๊ฒฝํ•œ๋‹ค.

https://steady-record.tistory.com/entry/Spring-Spring-Framework๋ž€#์Šคํ”„๋ง%20๋ฒ„์ „%20๋ฐ%20JDK%20๋ฒ„์ „%20์„ค์ •โ˜…-1

 

2. ์˜์กด์„ฑ ์ถ”๊ฐ€ - pom.xml

gson : ๊ตฌ๊ธ€์—์„œ ๋งŒ๋“  josn ํŒŒ์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.10.1</version>
		</dependency>

 

3. ์ปดํฌ๋„ŒํŠธ ์Šค์บ” - servlet-context.xml

์ง์ ‘ ์ƒ์„ฑํ•œ ํŒจ์ง€๋ฆฌ๋ฅผ ์Šคํ”„๋ง์ด ์Šค์บ”ํ•  ์ˆ˜ ์žˆ๋„๋ก  ๋“ฑ๋กํ•œ๋‹ค.

	<context:component-scan base-package="com.test.socket" />
	<context:component-scan base-package="com.test.controller" />
	<context:component-scan base-package="com.test.server" />

๊ตฌํ˜„ ์†Œ์Šค

- ChatController.java

package com.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ChatController {

	@GetMapping(value = "/index.do")
	public String index(Model model) {
		return "index";
	}
	
	@GetMapping(value = "/chat.do")
	public String chat(Model model) {
		return "chat";
	}
}

 

DB ์ž‘์—…์—†์ด ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์†Œํ†ตํ•  ๋•Œ๋Š” ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•  ์ผ์ด ์—†๋‹ค.

 


- Message.java

ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์—์„œ ์ฃผ๊ณ ๋ฐ›์„ ๋ฐ์ดํ„ฐ๋ฅผ DTO๋กœ ํฌ์žฅํ•œ๋‹ค. Lombok๋ฅผ ์„ค์น˜ํ•˜์ง€์•Š์•„ getter, setter๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

package com.test.domain;

//ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ
public class Message {
	
	private String code;		//์ƒํƒœ์ฝ”๋“œ
	private String sender;		//๋ณด๋‚ด๋Š” ์‚ฌ๋žŒ
	private String receiver;	//๋ฐ›๋Š” ์‚ฌ๋žŒ
	private String content;		//๋Œ€ํ™” ๋‚ด์šฉ
	private String regdate;		//๋‚ ์งœ
    
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getSender() {
		return sender;
	}
	public void setSender(String sender) {
		this.sender = sender;
	}
	public String getReceiver() {
		return receiver;
	}
	public void setReceiver(String receiver) {
		this.receiver = receiver;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	@Override
	public String toString() {
		return "Message [code=" + code + ", sender=" + sender + ", receiver=" + receiver + ", content=" + content
				+ ", regdate=" + regdate + "]";
	}
}

 


- ์ฑ„ํŒ…๋ฐฉ ์ž…์žฅํ•˜๊ธฐ

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocketTest- chat</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
</head>
<body>
	<!-- index.jsp -->
	<h1>WebSocket <small>chat</small></h1>
	
	<div>
		<div class="group">
			<label>๋‹‰๋„ค์ž„</label>
			<input type="text" name="name" id="name" class="short">
		</div>
	</div>
	
	<div>
		<button type="button" class="in">๋“ค์–ด๊ฐ€๊ธฐ</button>
	</div>
	
	<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
	
	<script>
	
		$('.in').click(function() {
			let name = $('#name').val();
			
			if ($(event.target).data('name') != null && $(event.target).data('name') != '') {
				name = $(event.target).data('name');
			}
			
			let child = window.open('/socket/chat.do', 'chat', 'width=405', 'height=510');
			
			child.addEventListener('load', function() {
				//์ž์‹์ฐฝ ๋‹ค ๋œจ๊ณ  ๋‚˜๋ฉด ๋ฐœ์ƒ
				child.connect(name);
			});
			
			//๋น„ํ™œ์„ฑํ™”
			$('.in').css('opacity', .5).prop('disabled', true);
			$('#name').prop('readOnly', true);
		});
	
	</script>
</body>
</html>

 

 

๋‹‰๋„ค์ž„์„ ์„ค์ •ํ•˜์—ฌ ๋“ค์–ด๊ฐ€๊ธฐ ๋ฒ„ํŠผ์œผ๋กœ ์ฑ„ํŒ…๋ฐฉ์— ์ž…์žฅํ•  ์ˆ˜ ์žˆ๋„๋กํ•œ๋‹ค.

 

์ฑ„ํŒ…๋ฐฉ ํŽ˜์ด์ง€๋ฅผ window.open์œผ๋กœ ์—ด๊ณ  child๋กœ ์ €์žฅํ•œ๋‹ค.

child๊ฐ€ load ๋˜๋ฉด ์ฑ„ํŒ…๋ฐฉํŽ˜์ด์ง€๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ๋“ค์–ด๊ฐ€๊ธฐ ๋ฒ„ํŠผ์€ ๋น„ํ™œ์„ฑํ™”ํ•œ๋‹ค.

 


- ์ฑ„ํŒ…๋ฐฉ ๋””์ž์ธ

chat.jsp - ์Šคํƒ€์ผ ์ •์˜

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocketTest- chat</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<style>
html, body {
		padding: 0 !important;
		margin: 0 !important;
		background-color: #FFF !important; 
		display: block;
		overflow: hidden;
	}
	
	body > div {
		margin: 0; 
		padding: 0; 
	}

	#main {
		width: 400px;
		height: 510px;
		margin: 3px;
		display: grid;
		grid-template-rows: repeat(12, 1fr);
	}
	#header > h2 {		
		margin: 0px;
		margin-bottom: 10px;
		padding: 5px;
	}

	#list {
		border: 1px solid var(--border-color);
		box-sizing: content-box;
		padding: .5rem;
		grid-row-start: 2;
		grid-row-end: 12;
		font-size: 14px;
		overflow: auto;
	}
	
	#msg {
		margin-top: 3px;
	}
	
	#list .item {
		font-size: 14px;
		margin: 15px 0;
	}
	
	#list .item > div:first-child {
		display: flex;
	}
	
	#list .item.me > div:first-child {
		justify-content: flex-end;
	}
	
	#list .item.other > div:first-child {
		justify-content: flex-end;
		flex-direction: row-reverse;
	}
	
	#list .item > div:first-child > div:first-child {
		font-size: 10px;
		color: #777;
		margin: 3px 5px;
	}
	
	#list .item > div:first-child > div:nth-child(2) {
		border: 1px solid var(--border-color);
		display: inline-block;
		min-width: 100px;
		max-width: 250px;
		text-align: left;
		padding: 3px 7px;
	}
	
	#list .state.item > div:first-child > div:nth-child(2) {
		background-color: #EEE;
	}
	
	#list .item > div:last-child {
		font-size: 10px;
		color: #777;
		margin-top: 5px;
	}
	
	#list .me {
		text-align: right;
	}
	
	#list .other {
		text-align: left;
	}
	
	#list .msg.me.item > div:first-child > div:nth-child(2) {
		background-color: rgba(255, 99, 71, .2);
	}
	
	#list .msg.other.item > div:first-child > div:nth-child(2) {
		background-color: rgba(100, 149, 237, .2);
	}
	
	#list .msg img {
		width: 150px;
	}
</style>
</head>
<body>
	<!-- chat.jsp  -->
	
	<div id="main">
		<div id="header"><h2>WebSocket <small>๋‹‰๋„ค์ž„</small></h2></div>
		<div id="list">
			
		</div>
		<input type="text" id="msg" placeholder = "๋Œ€ํ™” ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜์„ธ์š”.">
	</div>
	
	<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
</body>
</html>


- ์ž…์žฅ ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ

1. (ํด๋ผ์ด์–ธํŠธ)์„œ๋ฒ„ ์—ฐ๊ฒฐ ๋ฐ ์„œ๋ฒ„๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด ๋ณด๋‚ด๊ธฐ

chat.jsp 

	<script>
		let name;
		let ws;
		const url = 'ws://localhost:8090/socket/chatserver.do';
		
		function connect(name) {
			
			window.name = name;
			$('#header small').text(name);
			
			//์„œ๋ฒ„์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ > ์†Œ์ผ“ ์ƒ์„ฑ
			ws = new WebSocket(url);
			
			ws.onopen = function(evt) {
				log('์„œ๋ฒ„ ์—ฐ๊ฒฐ ์„ฑ๊ณต');
				
				let message = {
						code: '1',
						sender: window.name,
						receiver: '',
						content: '',
						regdate: new Date().toLocaleString()
				};
				
				//jOSN ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ํ›„ ์ „์†ก
				ws.send(JSON.stringify(message));
				print('', '๋Œ€ํ™”๋ฐฉ์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค.' , 'me', 'state', message.regdate);
				
				$('#msg').focus();
			};
		}//connect

 

 

const url = 'ws://localhost:8090/socket/chatserver.do';

์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ์ฃผ์†Œ์ด๋‹ค. ์„œ๋ฒ„์—์„œ๋Š” @ServerEndpoint("/chatserver.do") ์ข…๋‹จ์ ์„ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค.

 

ws = new WebSocket(url);

์„œ๋ฒ„ ์—ฐ๊ฒฐ

 

ws.onopen = function(evt) {

open ์ด๋ฒคํŠธ๋กœ ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ ์งํ›„ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•œ๋‹ค.

 

 

ํ”„๋กœํ† ์ฝœ์„ ์ด์šฉํ•œ ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ

์‚ฌ๋žŒ์ด ๋“ค์–ด์˜จ ์ƒํƒœ ๋ฐ ๋ฉ”์‹œ์ง€๋„ ws.send๋กœ ์ „๋‹ฌํ•œ๋‹ค.
์–ด๋–ค ์šฉ๋„์˜ ๋ฉ”์‹œ์ง€์ธ์ง€ ์„œ๋ฒ„์ธก์—์„œ๋Š” ์•Œ๊ธฐ ํž˜๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์‹œ์ง€์˜ ๊ทœ์น™์œผ๋กœ ๊ตฌ๋ถ„์ง€์–ด ์ „์†กํ•œ๋‹ค.

๋ฉ”์‹œ์ง€์˜ ๊ทœ์น™์œผ๋กœ ์ˆซ์ž๋Š” ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ  ๊ทธ ์ƒํƒœ์ฝ”๋“œ์— ๋”ฐ๋ผ ๋’ท ๋‚ด์šฉ์„ ๊ตฌ๋ถ„ ์ง“๋Š”๋‹ค.

ํ”„๋กœํ† ์ฝœ์€ ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์‹œ์ง€์˜ ํ˜•์‹๊ณผ ์˜๋ฏธ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ทœ

์น™์˜ ์ง‘ํ•ฉ์œผ๋กœ, ์ฃผ๊ณ  ๋ฐ›๋Š” ๋ฉ”์‹œ์ง€์˜ ๊ตฌ์กฐ๋ฅผ ํ†ต์ผํ•˜์—ฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์˜ ์›ํ™œํ•œ ํ†ต์‹ ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” ๋ฉ”์‹œ์ง€์˜ ๊ทœ์น™์„ JSON ํ˜•์‹์œผ๋กœ ์ •์˜ํ•˜๊ณ , ์ˆซ์ž๋กœ ํ‘œํ˜„๋œ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฉ”์‹œ์ง€ ์œ ํ˜•์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

  • code : ์ƒํƒœ์ฝ”๋“œ
    • 1 : ์ƒˆ๋กœ์šด ์œ ์ €๊ฐ€ ๋“ค์–ด์˜ด
    • 2: ๊ธฐ์กด ์œ ์ €๊ฐ€ ๋‚˜๊ฐ
    • 3: ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ
    • 4: ์ด๋ชจํ‹ฐ์ฝ˜ ์ „๋‹ฌ
  • sender : ๋ณด๋‚ด๋Š” ์œ ์ €๋ช…
  • receiver : ๋ฐ›๋Š” ์œ ์ €๋ช…
  • content : ๋Œ€ํ™” ๋‚ด์šฉ
  • regdate : ๋‚ ์งœ/์‹œ๊ฐ„

 

ws.send(JSON.stringify(message));

message ๊ฐ์ฒด๋ฅผ JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์›น ์†Œ์ผ“์„ ํ†ตํ•ด ์„œ๋ฒ„๋กœ ์ „์†กํ•œ๋‹ค.

 

 

2. (์„œ๋ฒ„) ํด๋ผ์ด์–ธํŠธ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ ๋ฐ›๊ธฐ ๋ฐ ์ „์†กํ•˜๊ธฐ

ChatServer.java

package com.test.server;

@ServerEndpoint("/chatserver.do")
public class ChatServer {

	private static List<Session> sessionList = new ArrayList<Session>();
	
	@OnOpen
	public void handleOpen(Session session) {
		sessionList.add(session);
		checkSessionList();			//์ ‘์†์ž ํ™•์ธ
	}
	
	@OnMessage
	public void handleMessage(String msg, Session session) {
		System.out.println(msg);
		
		Gson gson = new Gson();
		
	 	Message message =  gson.fromJson(msg, Message.class);
		
	 	if (message.getCode().equals("1")) {
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
	 					s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	} 
	}
	
	//์ ‘์†์ž๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ
	private void checkSessionList() {
		System.out.println();
		System.out.println("[Session List]");
		for (Session session : sessionList) {
			System.out.println(session.getId());
		}
		System.out.println();
	}
	
}

 

@ServerEndpoint("/chatserver.do")

์›น ์†Œ์ผ“ ํ†ต์‹ ์„ ์œ„ํ•œ ์—”๋“œํฌ์ธํŠธ ํด๋ž˜์Šค๋กœ์„œ, ํด๋ผ์ด์–ธํŠธ์™€์˜ ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌํ•˜๊ณ  ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋กœ์ง์„ ํ•ด๋‹น ํด๋ž˜์Šค์— ์ž‘์„ฑํ•œ๋‹ค.

 

private static List<Session> sessionList = new ArrayList<Session>();

์„œ๋ฒ„์—์„œ๋Š” ์œ ์ €1์˜ ์†Œ์ผ“๊ณผ ์œ ์ €2์˜ ์†Œ์ผ“์„ ๊ฐ๊ฐ ๊ด€๋ฆฌ๋ฅผ ํ•ด์•ผํ•œ๋‹ค. 1๋ช… ์ด์ƒ์ด ์ ‘์†ํ•˜๊ธฐ์— arraylist๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค.

websocket์˜ session์€ ์ฑ„ํŒ…์— ์ ‘์†ํ•œ ํด๋ผ์ด์–ธํŠธ์˜ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ ‘์†ํ–ˆ์„ ๋•Œ list์— session์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

@OnOpen

public void handleOpen(Session session) {

WebSocket ์—ฐ๊ฒฐ์ด ์—ด๋ฆด ๋•Œ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋œ๋‹ค.

 

sessionList.add(session);

์ ‘์†ํ•œ ํด๋ผ์ด์–ธํŠธ์˜ ์„ธ์…˜์„ ์ €์žฅํ•œ๋‹ค.

 

@OnMessage
public void handleMessage(String msg, Session session) {

ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ ํ˜ธ์ถœ๋œ๋‹ค.

 

Gson gson = new Gson();

Gson : JSON ํ˜•์‹์˜ ๋ฌธ์ž์—ด์„ ์ž๋ฐ”ํด๋ž˜์Šค ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

์œ„์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ msg๋ฅผ JSON์„ ์ „์†ก์„ ํ•˜์˜€์œผ๋ฉฐ, ์ž๋ฐ”ํด๋ž˜์Šค์—์„œ ํ•ด์„๊ฐ€๋Šฅํ•˜๋„๋ก ๋‹ค์‹œ ์ž๋ฐ”ํด๋ž˜์Šค ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

 

Message message =  gson.fromJson(msg, Message.class);

SON ํ˜•์‹์˜ ๋ฌธ์ž์—ด(msg)์„ Gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Java ๊ฐ์ฒด(Message ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค)๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

 

if (message.getCode().equals("1")) {
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
	 					s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	}

 

 

๋ชจ๋“  ์ ‘์†์ž ์ค‘์—์„œ ๋ฐฉ๊ธˆ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ ์„ธ์…˜์„ ์ œ์™ธํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์„ธ์…˜์„ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
๋ณธ์ธ์ด์™ธ์˜ ์„ธ์…˜(์†Œ์ผ“)์—๊ฒŒ ํ˜„์žฌ ์ ‘์†์ž๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.

getBasicRemote() : ์„ธ์…˜๊ณผ ๊ด€๋ จ๋œ ์†Œ์ผ“์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ

sendText() : ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ๋‹ค. 

 

3. (ํด๋ผ์ด์–ธํŠธ) ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ธฐ

chat.jsp

	<script>
	
		let name;
		let ws;
		const url = 'ws://localhost:8090/socket/chatserver.do';
		
		function connect(name) {
			
			window.name = name;
			$('#header small').text(name);
			
			ws = new WebSocket(url);
			
			ws.onopen = function(evt) {
				
				let message = {
						code: '1',
						sender: window.name,
						receiver: '',
						content: '',
						regdate: new Date().toLocaleString()
				};
				
				//jOSN ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ํ›„ ์ „์†ก
				ws.send(JSON.stringify(message));
				print('', '๋Œ€ํ™”๋ฐฉ์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค.' , 'me', 'state', message.regdate);
				
				$('#msg').focus();
			};
			
			//์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•œ ๋ฉ”์‹œ์ง€
			ws.onmessage = function(evt) {
				let message = JSON.parse(evt.data);
				
				if (message.code == '1') {
					print('', `[\${message.sender}]๋‹˜์ด ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} 
			}
			
			
		}//connect
		
		function log(msg) {
			console.log(`[\${new Date().toLocaleTimeString()}] \${msg}`);
		}
		
		//๋Œ€ํ™”์ฐฝ ์ถœ๋ ฅ ๋ฉ”์†Œ๋“œ
		function print(name, msg, side, state, time) {
			let temp = `
				<div class="item \${state} \${side}">
					<div>
						<div>\${name}</div>
						<div>\${msg}</div>
					</div>
					<div>\${time}</div>
				</div>`;
			
			$('#list').append(temp);
			
			//์ƒˆ๋กœ์šด ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋˜๋ฉด ์Šคํฌ๋กค์„ ๋ฐ”๋‹ฅ์œผ๋กœ ๋‚ด๋ฆฐ๋‹ค.
			scrollList();
		}
		
		function scrollList() {
			$('#list').scrollTop($('#list').outerHeight() + 300);
		}
	
	</script>

 

onmessage ์ด๋ฒคํŠธ๋กœ ์„œ๋ฒ„์—์„œ ์ „๋‹ฌ๋ฐ›์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

 

์ถœ๋ ฅํ˜•์‹์„ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ถœ๋ ฅ์ด ํ•„์š”ํ•  ๋•Œ ์–‘์‹์— ๋งž์ถฐ ์ถœ๋ ฅํ•œ๋‹ค.

 

 


- ํ‡ด์žฅ ๋ฉ”์‹œ์ง€ ๋„์šฐ๊ธฐ

๋Œ€ํ™”์ฐฝ์„ ๋‹ซ์•˜์„ ๋•Œ ํ‡ด์žฅํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

 

1. (ํด๋ผ์ด์–ธํŠธ) ํ‡ด์žฅํ•œ ์œ ์ € ์ •๋ณด ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๊ธฐ

chat.jsp

	<script>
		$(window).on('beforeunload', function() {
			disconnect();
		});
		
		function disconnect() {
			//๋Œ€ํ™”๋ฐฉ์—์„œ ๋‚˜๊ฐ€๋ฉด, ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์•ˆ๋‚ด๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค.
			let message = {
					code: '2',
					sender: window.name,
					receiver: '',
					content: '',
					regdate: new Date().toLocaleString()
			};
			
			//jOSN ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ํ›„ ์ „์†ก
			ws.send(JSON.stringify(message));
		}
	</script>

 

beforeunload

์ฐฝ์ด ๋‹ซํžˆ๊ธฐ ๋ฐ”๋กœ ์ง์ „์— ๋ฐœ์ƒํ•œ๋‹ค.

 

๋Œ€ํ™”๋ฐฉ์—์„œ ๋‚˜๊ฐ€๋ฉด, ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์•ˆ๋‚ด๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„๋กœ ๋ณด๋‚ผ ๋ฉ”์‹œ์ง€๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

๋Œ€ํ™”๋ฐฉ์—์„œ ๋‚˜๊ฐ„๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ฝ”๋“œ 2๋ฒˆ์œผ๋กœ ์ •ํ•œ๋‹ค.

๋ฐฐ์—ด๋กœ ์ž‘์„ฑํ•œ ๋ฉ”์‹œ์ง€๋ฅผ JSON ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ํ›„ ์„œ๋ฒ„๋กœ ์ „์†กํ•œ๋‹ค.

 

2. (์„œ๋ฒ„) ํด๋ผ์ด์–ธํŠธ ๋ฉ”์‹œ์ง€ ์†ก์ˆ˜์‹  ๋ฐ ์„ธ์…˜ ์ œ๊ฑฐ

package com.test.server;

@ServerEndpoint("/chatserver.do")
public class ChatServer {
	@OnOpen
	public void handleOpen(Session session) {
		sessionList.add(session);
		checkSessionList();			//์ ‘์†์ž ํ™•์ธ
		clearSessionList();			
	}
	
	@OnMessage
	public void handleMessage(String msg, Session session) {
		System.out.println(msg);
		
		Gson gson = new Gson();
		
	 	Message message =  gson.fromJson(msg, Message.class);
		
	 	if (message.getCode().equals("1")) { //์ƒ๋Œ€๋ฐฉ ๋Œ€ํ™”๋ฐฉ ์ž…์žฅ
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
	 					s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	} else if (message.getCode().equals("2")) { 
	 		sessionList.remove(session);
	 		for (Session s : sessionList) {
	 			try {
	 				s.getBasicRemote().sendText(msg);
				} catch (Exception e) {
					e.printStackTrace();
				}
	 		}
	 	}
	}
	
	//์ ‘์†์ž๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฉ”์„œ๋“œ
	private void checkSessionList() {
		System.out.println();
		System.out.println("[Session List]");
		for (Session session : sessionList) {
			System.out.println(session.getId());
		}
		System.out.println();
	}
	
	//์•ˆ์ •์„ฑ์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ : ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ์„ธ์…˜์ด ์žˆ์œผ๋ฉด ์„ธ์…˜๋ฆฌ์ŠคํŠธ์—์„œ ์ œ๊ฑฐํ•œ๋‹ค.
	private void clearSessionList() {
		
		//List ๊ณ„์—ด์˜ ์ปฌ๋ ‰์…˜์€ ํ–ฅ์ƒ๋œ for๋ฌธ ๋‚ด์—์„œ ์š”์†Œ ์ถ”๊ฐ€/์‚ญ์ œํ•˜๋Š” ํ–‰๋™์„ ํ•  ์ˆ˜ ์—†๋‹ค.
		//๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์€ 1. ์ผ๋ฐ˜ forans, 2. Interator ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
		Iterator<Session> iter = sessionList.iterator();
		
		while(iter.hasNext()) {
			if(!(iter.next()).isOpen()) {
				//ํ˜น์‹œ ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ์„ธ์…˜์ด ์žˆ์œผ๋ฉด ๋ฆฌ์ŠคํŠธ์—์„œ ์ œ๊ฑฐํ•œ๋‹ค.
				iter.remove();
			}
		}
		
	}
	
}

 

clearSessionList()

์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ์„ธ์…˜์ด ์žˆ์œผ๋ฉด ์„ธ์…˜๋ฆฌ์ŠคํŠธ์—์„œ ์ œ๊ฑฐํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

์ƒ๋Œ€๋ฐฉ์ด ๋‚˜๊ฐ„๋‹ค๋Š” ์˜๋ฏธ์ธ ์ฝ”๋“œ 2๋ฒˆ์„ ์ˆ˜์‹ ๋ฐ›์•˜์„ ๋•Œ, ์„ธ์…˜์„ ์ œ๊ฑฐํ•˜์ง€๋งŒ, ์•ˆ์ •์„ฑ์„ ์œ„ํ•ด ์›น์†Œ์ผ“์ด ์—ด๋ ธ์„ ๋•Œ, ๋‹ค์‹œ ํ•œ๋ฒˆ ํ™•์ธํ•œ๋‹ค.

 

์ฝ”๋“œ 2๋ฒˆ์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ๋ฐ›์•˜์„ ๋•Œ,

1. session ์ œ๊ฑฐ

2. ๋‚˜๋จธ์ง€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์œ ์ € ํ‡ด์žฅ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค.

 

3. (ํด๋ผ์ด์–ธํŠธ) ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ธฐ

chat.jsp

	<script>
		let name;
		let ws;
		const url = 'ws://localhost:8090/socket/chatserver.do';
		
		function connect(name) {
			
			window.name = name;
			$('#header small').text(name);
			
			ws = new WebSocket(url);
			
			ws.onopen = function(evt) {
				
				let message = {
						code: '1',
						sender: window.name,
						receiver: '',
						content: '',
						regdate: new Date().toLocaleString()
				};
				
				ws.send(JSON.stringify(message));
				print('', '๋Œ€ํ™”๋ฐฉ์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค.' , 'me', 'state', message.regdate);
				
				$('#msg').focus();
			};
			
			ws.onmessage = function(evt) {
				
				let message = JSON.parse(evt.data);
				console.log(message);
				
				if (message.code == '1') {
					print('', `[\${message.sender}]๋‹˜์ด ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} else if (message.code == '2') {
					print('', `[\${message.sender}]๋‹˜์ด ๋‚˜๊ฐ”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} 
			}
		}//connect
		
		function log(msg) {
			console.log(`[\${new Date().toLocaleTimeString()}] \${msg}`);
		}
		
		function print(name, msg, side, state, time) {
			let temp = `
				<div class="item \${state} \${side}">
					<div>
						<div>\${name}</div>
						<div>\${msg}</div>
					</div>
					<div>\${time}</div>
				</div>`;
			
			$('#list').append(temp);
			
			//์ƒˆ๋กœ์šด ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋˜๋ฉด ์Šคํฌ๋กค์„ ๋ฐ”๋‹ฅ์œผ๋กœ ๋‚ด๋ฆฐ๋‹ค.
			scrollList();
		}
		
		$(window).on('beforeunload', function() {
			disconnect();
		});
		
		function disconnect() {
			let message = {
					code: '2',
					sender: window.name,
					receiver: '',
					content: '',
					regdate: new Date().toLocaleString()
			};
			
			ws.send(JSON.stringify(message));
		}
		
		
		//๋Œ€ํ™” ์Šคํฌ๋กค ์ด๋ฒคํŠธ
		function scrollList() {
			$('#list').scrollTop($('#list').outerHeight() + 300);
		}
	</script>

 

print ๋ฉ”์†Œ๋“œ๋กœ ๋‚˜๊ฐ„ ์œ ์ €์˜ ์ด๋ฆ„์œผ๋กœ ํ‡ด์žฅ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.


- ์ฑ„ํŒ…ํ•˜๊ธฐ

1. (ํด๋ผ์ด์–ธํŠธ) ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†กํ•˜๊ธฐ

chat.jsp

	<script>
		$('#msg').keydown(function(evt) {
			//์—”ํ„ฐ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ, ์ž…๋ ฅํ•œ ๋Œ€ํ™” ๋‚ด์šฉ์„ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๊ธฐ
			if (evt.keyCode == 13) {	//์—”ํ„ฐ
				let message = {
						code: '3',
						sender: window.name,
						receiver: '',
						content: $('#msg').val(),
						regdate: new Date().toLocaleString()
				};
			
				ws.send(JSON.stringify(message));		
				
				$('#msg').val('').focus();
				
				print(window.name, message.content, 'me', 'msg', message.regdate);
			}
		});
		
	</script>

 

์—”ํ„ฐ์˜ ์•„์Šคํ‚ค์ฝ”๋“œ ๊ฐ’์œผ๋กœ ์—”ํ„ฐ๋ฅผ ์ธ์‹ํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ๋‹ค.

์ฑ„ํŒ… ๋ฉ”์‹œ์ง€ ์†ก๋ถ€๋Š” ์ฝ”๋“œ 3๋ฒˆ์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.

์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ ๋’ค msg ํ…์ŠคํŠธ ๋ฐ•์Šค๋Š” ๋‹ค์Œ ์ž…๋ ฅ์„ ์œ„ํ•ด ๋นˆ์นธ์œผ๋กœ ๋‘๊ณ  ํฌ์ปค์Šค๋ฅผ ๋งž์ถ˜๋‹ค. 

๋ณด๋‚ธ ๋ฉ”์‹œ์ง€๋Š” ๋ฐ”๋กœ ๋ณธ์ธ์˜ ํ™”๋ฉด์—์„œ ์ถœ๋ ฅํ•œ๋‹ค.

 

 

2. (์„œ๋ฒ„) ํด๋ผ์ด์–ธํŠธ ๋ฉ”์‹œ์ง€ ์†ก์ˆ˜์‹ 

ChatServer.java

package com.test.server;

@ServerEndpoint("/chatserver.do")
public class ChatServer {
	@OnOpen
	public void handleOpen(Session session) {
		sessionList.add(session);
		checkSessionList();			//์ ‘์†์ž ํ™•์ธ
		clearSessionList();			
	}
	
	@OnMessage
	public void handleMessage(String msg, Session session) {
		System.out.println(msg);
		
		Gson gson = new Gson();
		
	 	Message message =  gson.fromJson(msg, Message.class);
		
	 	if (message.getCode().equals("1")) { //์ƒ๋Œ€๋ฐฉ ๋Œ€ํ™”๋ฐฉ ์ž…์žฅ
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
	 					s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	} else if (message.getCode().equals("2")) { 
	 		sessionList.remove(session);
	 		for (Session s : sessionList) {
	 			try {
	 				s.getBasicRemote().sendText(msg);
				} catch (Exception e) {
					e.printStackTrace();
				}
	 		}
	 	} else if (message.getCode().equals("3")) {	
	 		//๋ณด๋‚ธ ์‚ฌ๋žŒ๋นผ๊ณ  ๋‚˜๋จธ์ง€ ์‚ฌ๋žŒ์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
						s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 		
	 	} 
	}
}

 

 

3. (ํด๋ผ์ด์–ธํŠธ) ์ฑ„ํŒ… ์ถœ๋ ฅํ•˜๊ธฐ

chat.jsp

	<script>
		function connect(name) {
			
			ws.onmessage = function(evt) {
				
				let message = JSON.parse(evt.data);
				console.log(message);
				
				if (message.code == '1') {
					print('', `[\${message.sender}]๋‹˜์ด ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} else if (message.code == '2') {
					print('', `[\${message.sender}]๋‹˜์ด ๋‚˜๊ฐ”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} else if (message.code == '3') {
					print(message.sender, message.content, 'other', 'msg', message.regdate);
				}
			}
		}//connect
		
	</script>

 

์ฑ„ํŒ….png


- ์ด๋ชจํ‹ฐ์ฝ˜(์ด๋ฏธ์ง€) ๋ณด๋‚ด๊ธฐ

'/'๋ฅผ ์•ž์— ์ž…๋ ฅํ•˜๊ณ  ํŒŒ์ผ๋ช…์„ ์ ์œผ๋ฉด ํ•ด๋‹น ์ด๋ฏธ์ง€๊ฐ€ ์ „์†ก๋œ๋‹ค.

 

1. (ํด๋ผ์ด์–ธํŠธ) ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€ ์ „์†กํ•˜๊ธฐ

chat.jsp

	<script>
		$('#msg').keydown(function(evt) {
			//์—”ํ„ฐ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ, ์ž…๋ ฅํ•œ ๋Œ€ํ™” ๋‚ด์šฉ์„ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๊ธฐ
			if (evt.keyCode == 13) {	//์—”ํ„ฐ
				let message = {
						code: '3',
						sender: window.name,
						receiver: '',
						content: $('#msg').val(),
						regdate: new Date().toLocaleString()
				};
			
				//์ „์†ก๋ฉ”์‹œ์ง€ '/'๋กœ ์‹œ์ž‘ํ•˜๋ฉด ์ด๋ชจํ‹ฐ์ฝ˜ ์ „์†ก์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.
				if ($('#msg').val().startsWith('/')) {
					message.code = '4';
				}
			
				ws.send(JSON.stringify(message));		
				
				$('#msg').val('').focus();
				
				if (message.code == '3') {
					print(window.name, message.content, 'me', 'msg', message.regdate);
				} else if (message.code == '4') {
					printEmoticon(window.name, message.content, 'me', 'msg', message.regdate);
				}
			}
		});
        
        	//์ด๋ชจํ‹ฐ์ฝ˜ ์ถœ๋ ฅ ๋ฉ”์†Œ๋“œ
		function printEmoticon(name, msg, side, state, time) {
			
			let temp = `
				<div class="item \${state} \${side}">
					<div>
						<div>\${name}</div>
						<div style = "background-color:#fff; boarder:0;"><img src="/socket/resources/emoticon/\${msg}.png"></div>
					</div>
					<div>\${time}</div>
				</div>
			`;
			
			$('#list').append(temp);
			
			//์ƒˆ๋กœ์šด ๋‚ด์šฉ์ด ์ถ”๊ฐ€๋˜๋ฉด ์Šคํฌ๋กค์„ ๋ฐ”๋‹ฅ์œผ๋กœ ๋‚ด๋ฆฐ๋‹ค. (์ด๋ฏธ์ง€ ๋กœ๋”ฉ์ด ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์„œ 0.1์ดˆ์˜ ์‹œ๊ฐ„์ฐจ๋ฅผ ๋‘”๋‹ค.)
			setTimeout(scrollList, 100);
		}
		
	</script>

 

 

2. (์„œ๋ฒ„) ํด๋ผ์ด์–ธํŠธ ๋ฉ”์‹œ์ง€ ์†ก์ˆ˜์‹ 

ChatServer.java

package com.test.server;

@ServerEndpoint("/chatserver.do")
public class ChatServer {
	@OnOpen
	public void handleOpen(Session session) {
		sessionList.add(session);
		checkSessionList();			//์ ‘์†์ž ํ™•์ธ
		clearSessionList();			
	}
	
	@OnMessage
	public void handleMessage(String msg, Session session) {
		System.out.println(msg);
		
		Gson gson = new Gson();
		
	 	Message message =  gson.fromJson(msg, Message.class);
		
	 	if (message.getCode().equals("1")) { //์ƒ๋Œ€๋ฐฉ ๋Œ€ํ™”๋ฐฉ ์ž…์žฅ
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
	 					s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	} else if (message.getCode().equals("2")) { 
	 		sessionList.remove(session);
	 		for (Session s : sessionList) {
	 			try {
	 				s.getBasicRemote().sendText(msg);
				} catch (Exception e) {
					e.printStackTrace();
				}
	 		}
	 	} else if (message.getCode().equals("3")) {		//์ƒ๋Œ€๋ฐฉ ๋ฉ”์‹œ์ง€ ์ „์†ก
	 		//๋ณด๋‚ธ ์‚ฌ๋žŒ๋นผ๊ณ  ๋‚˜๋จธ์ง€ ์‚ฌ๋žŒ์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
						s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	} else if (message.getCode().equals("4")) {		//์ƒ๋Œ€๋ฐฉ ๋ฉ”์‹œ์ง€ ์ „์†ก
	 		for (Session s : sessionList) {
	 			if (s != session) {
	 				try {
						s.getBasicRemote().sendText(msg);
					} catch (Exception e) {
						e.printStackTrace();
					}
	 			}
	 		}
	 	}
	}
}

 

3. (ํด๋ผ์ด์–ธํŠธ) ์ฑ„ํŒ… ์ถœ๋ ฅํ•˜๊ธฐ

chat.jsp

	<script>
		function connect(name) {
			
			ws.onmessage = function(evt) {
				
				let message = JSON.parse(evt.data);
				console.log(message);
				
				if (message.code == '1') {
					print('', `[\${message.sender}]๋‹˜์ด ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} else if (message.code == '2') {
					print('', `[\${message.sender}]๋‹˜์ด ๋‚˜๊ฐ”์Šต๋‹ˆ๋‹ค.`, 'other', 'state', message.regdate);
				} else if (message.code == '3') {
					print(message.sender, message.content, 'other', 'msg', message.regdate);
				} else if (message.code == '4') {
					printEmoticon(message.sender, message.content, 'other', 'msg', message.regdate);
				}
			}
		}//connect
		
	</script>