본문 바로가기
  • Welcome J-Kyu Tstory
Spring

[SpringFramework]소켓으로 채팅 구현

by regularity 2022. 8. 2.
728x90

1. 프로젝트 구성

 

2. socket사용을 위한 pom.xml 디펜던시 추가

<!-- 소켓 디펜던시 -->
    <dependency> 
       <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId> 
        <version>2.9.4</version> 
     </dependency> 
 
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-websocket</artifactId>
	    <version>${org.springframework-version}</version>
	</dependency>
    
     <dependency>
        <groupId>javax.websocket</groupId>
        <artifactId>javax.websocket-api</artifactId>
        <version>1.1</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>

 

3. web.xml에 server디펜던시 추가

	
	<!-- 소켓 서버 -->
	<servlet>
		<servlet-name>WARINGSOCKET</servlet-name>
		<servlet-class>bgm.bgmaster.ex.WaringSocketServer</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

 

4. Handler.java 추가

package bgm.bgmaster.ex;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
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;

@RequestMapping("/echo")
public class EchoHandler extends TextWebSocketHandler{
	 //세션 리스트
    private List<WebSocketSession> sessionList = new ArrayList<WebSocketSession>();

    private static Logger logger = LoggerFactory.getLogger(EchoHandler.class);

    //클라이언트가 연결 되었을 때 실행
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessionList.add(session);
        logger.info("{} 연결됨", session.getId()); 
    }

    //클라이언트가 웹소켓 서버로 메시지를 전송했을 때 실행
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        logger.info("{}로 부터 {} 받음", session.getId(), message.getPayload());
        //모든 유저에게 메세지 출력
        for(WebSocketSession sess : sessionList){
            sess.sendMessage(new TextMessage(message.getPayload()));
        }
    }

    //클라이언트 연결을 끊었을 때 실행
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessionList.remove(session);
        logger.info("{} 연결 끊김.", session.getId());
    }
}

 

5. SocketServer.java 추가

package bgm.bgmaster.ex;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WaringSocketServer extends HttpServlet implements Runnable{

	private static final Logger logger = LoggerFactory.getLogger(WaringSocketServer.class);
	private Thread deamon;
	
	public void init() throws ServletException{
		
		deamon= new Thread(this); // deamon.setPriority(Thread.MIN_PRIORITY);
		deamon.start();
	}
	public void destroy() {
		deamon.interrupt();
	}
	public void run() {
		try {
			logger.info("========================");
			logger.info("WaringSocketServer RUN");
			logger.info("========================");
			warningInit();
		}catch (Exception e) {
			logger.info("ServerSocket failed : "+e.getMessage());
			return;
		}
	}
	public void warningInit() {
		try {
			ServerSocket warningServer = new ServerSocket(8081);
			while(true) {
				try {
					logger.info("Traffic Client Request Waiting!");
					Socket warningSocket = warningServer.accept();	//클라이언트 접속떄까지 대기
					
					logger.info("Traffic Socket Client Access IP: "+warningSocket.getInetAddress());
					
					BufferedReader in = new BufferedReader(new InputStreamReader(warningSocket.getInputStream()));
					PrintWriter out = new PrintWriter(new OutputStreamWriter(warningSocket.getOutputStream()));
					
					//클라이언트 소켓으로부터 받은 메시지를 화면에 출력
					String reqMsg = in.readLine();
					//System.out.println("클라이언트로 부터 받은 메시지:"+in.readLine());
					logger.info("Client Request Message : "+ reqMsg);
					
					//클라이언트 소켓에 메시지전송
					//out,println(reqMsg);
					//out.flush();
					
					warningSocket.close();
				}catch (IOException ie) {
					ie.printStackTrace();
				}
			}
		}catch (MalformedURLException e) {
			logger.info(e.toString());
		}catch(IOException e) {
			logger.info(e.toString());
		}
	}
}

6. 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 http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>웹소켓 채팅</title>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.4.0/sockjs.js"></script>
	<script type="text/javascript">
		var webSocket = {
			init: function(param) {
				this._url = param.url;
				this._initSocket();
			},
			sendChat: function() {
				this._sendMessage($('#message').val());
				$('#message').val('');
			},
			receiveMessage: function(str) {
				$('#divChatData').append('<div>' + str + '</div>');				
			},
			closeMessage: function(str) {
				$('#divChatData').append('<div>' + '연결 끊김 : ' + str + '</div>');
			},
			disconnect: function() {
				this._socket.close();
			},
			_initSocket: function() {
				this._socket = new SockJS("http://외부접속 IP:8080/echo");
				this._socket.onmessage = function(evt) {
					webSocket.receiveMessage(evt.data);
				};
				this._socket.onclose = function(evt) {
					webSocket.closeMessage(evt.data);
				}
			},
			_sendMessage: function(str) {
				this._socket.send(str);
			}
		};
	</script>	
	<script type="text/javascript">
		$(document).ready(function() {
			webSocket.init({ url: '<c:url value="/chat" />' });			
		});
	</script>
</head>
<body>
	<div style="width: 800px; height: 700px; padding: 10px; border: solid 1px #e1e3e9;">
		<div id="divChatData"></div>
	</div>
	<div style="width: 100%; height: 10%; padding: 10px;">
		<input type="text" id="message" size="110" onkeypress="if(event.keyCode==13){webSocket.sendChat();}" />
		<input type="button" id="btnSend" value="채팅 전송" onclick="webSocket.sendChat()" />
	</div>
</body>
</html>

 

( new SockJS("http://외부접속 IP:8080/echo"); 에서 외부접속ip는  외부에서 서버pc로 접속할 때필요한 공인ip주소로 서버피씨의 공인ip주소를 적으면 됨)

728x90

댓글