반응형
출처사이트 : https://devmg.tistory.com/m/127
File > New > Spring Lagacy Project > Templates목록에서 맨 아레 Spring MVC Project 클릭 하고 생성
※만약에 Spring Lagacy Project가 보이지 않는다면 마켓플레이스에서 STS를 입력후 STS3 Add-On 설치한다.
<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>
</dependency>
기본 pom.xml에 2개의 의존성을 추가한다.
위 대로 디폴트 스프링mvc프로젝트를 생성하면 버전이 낮다. 그래서 웹소켓 인터페이스를 지원하는데 오류가 많이 났다 (자바 1.6/ 스프링3 / 웹모듈 2.5....)
그래서 자바 1.8, 스프링4, 웹모듈 3.0로 버전 업그레이드를 하니 오류가 사라졌다.
스프링 버전 올리기 ↓
https://offbyone.tistory.com/16
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported> <!-- 웹소켓을 위한 설정(비동기지원) -->
</servlet>
기본 web.xml에 async-supported 속성을 추가한다.
LoginController.java
package com.devmg.app;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Handles requests for the application home page.
*/
@Controller
public class LoginController {
private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/login.do", method = RequestMethod.GET)
public String login() {
return "login";
}
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/loginProcess.do", method = RequestMethod.POST)
public String loginProcess(@RequestParam String id, HttpServletRequest request) {
logger.info("Welcome "+id);
HttpSession session = request.getSession();
session.setAttribute("id", id);
return "chat";
}
}
로그인 페이지 이동 및 사용자 로그인 세션 만들기
WebSocketChat.java
package com.devmg.app;
import java.util.ArrayList;
import java.util.List;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.RemoteEndpoint.Basic;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
@Controller
@ServerEndpoint(value="/echo.do")
public class WebSocketChat {
private static final List<Session> sessionList=new ArrayList<Session>();;
private static final Logger logger = LoggerFactory.getLogger(WebSocketChat.class);
public WebSocketChat() {
// TODO Auto-generated constructor stub
System.out.println("웹소켓(서버) 객체생성");
}
@OnOpen
public void onOpen(Session session) {
logger.info("Open session id:"+session.getId());
try {
final Basic basic=session.getBasicRemote();
basic.sendText("대화방에 연결 되었습니다.");
}catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
sessionList.add(session);
}
/*
* 모든 사용자에게 메시지를 전달한다.
* @param self
* @param sender
* @param message
*/
private void sendAllSessionToMessage(Session self, String sender, String message) {
try {
for(Session session : WebSocketChat.sessionList) {
if(!self.getId().equals(session.getId())) {
session.getBasicRemote().sendText(sender+" : "+message);
}
}
}catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
}
/*
* 내가 입력하는 메세지
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message,Session session) {
String sender = message.split(",")[1];
message = message.split(",")[0];
logger.info("Message From "+sender + ": "+message);
try {
final Basic basic=session.getBasicRemote();
basic.sendText("<나> : "+message);
}catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
sendAllSessionToMessage(session, sender, message);
}
@OnError
public void onError(Throwable e,Session session) {
}
@OnClose
public void onClose(Session session) {
logger.info("Session "+session.getId()+" has ended");
sessionList.remove(session);
}
}
웹소켓을 이용한 채팅 메세지 수신/발신 모듈이다.
각 @어노테이션의 설명은 생략
login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/latest/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: #f8f8f8;
padding: 60px 0;
}
#login-form > div {
margin: 15px 0;
}
</style>
<title>Home</title>
</head>
<div class="container">
<div class="col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
<div class="panel panel-success">
<div class="panel-heading">
<div class="panel-title">환영합니다!</div>
</div>
<div class="panel-body">
<form id="login-form" method="post" action="/loginProcess.do">
<div>
<input type="text" name="id" class="form-control" name="아이디 입력" placeholder="Username" autofocus>
</div>
<div>
<button type="submit" class="form-control btn btn-primary">로그인</button>
</div>
</form>
</div>
</div>
</div>
</div>
</html>
로그인 폼
chat.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple Chat</title>
</head>
<body>
<div>
<button type="button" onclick="openSocket();">대화방 참여</button>
<button type="button" onclick="closeSocket();">대회방 나가기</button>
<br/><br/><br/>
메세지 입력 :
<input type="text" id="sender" value="${sessionScope.id}" style="display: none;">
<input type="text" id="messageinput">
<button type="button" onclick="send();">메세지 전송</button>
<button type="button" onclick="javascript:clearText();">대화내용 지우기</button>
</div>
<!-- Server responses get written here -->
<div id="messages">
</div>
<!-- websocket javascript -->
<script type="text/javascript">
var ws;
var messages = document.getElementById("messages");
function openSocket(){
if(ws !== undefined && ws.readyState !== WebSocket.CLOSED ){
writeResponse("WebSocket is already opened.");
return;
}
//웹소켓 객체 만드는 코드
ws = new WebSocket("ws://localhost:8080/echo.do");
ws.onopen = function(event){
if(event.data === undefined){
return;
}
writeResponse(event.data);
};
ws.onmessage = function(event){
console.log('writeResponse');
console.log(event.data)
writeResponse(event.data);
};
ws.onclose = function(event){
writeResponse("대화 종료");
}
}
function send(){
// var text=document.getElementById("messageinput").value+","+document.getElementById("sender").value;
var text = document.getElementById("messageinput").value+","+document.getElementById("sender").value;
ws.send(text);
text = "";
}
function closeSocket(){
ws.close();
}
function writeResponse(text){
messages.innerHTML += "<br/>"+text;
}
function clearText(){
console.log(messages.parentNode);
messages.parentNode.removeChild(messages)
}
</script>
</body>
</html>
채팅방 폼
원본소스의 깃 ↓
github.com/DevMoonKi/SimpleChat
위와같이 개발하면 톰캣에서는 잘되지만 제우스등에 was에서는 안될수 있다.
제우스에 webSocket 세팅이 별도로 필요하다.
제우스 엔지니어에게 요청 필요.
//CODE
반응형
'웹개발 > jsp' 카테고리의 다른 글
자바단(서비스단)에서 직접 특정 웹사이트 URL호출 하기 (0) | 2022.02.17 |
---|---|
xss 방지 (0) | 2022.02.17 |
HttpSessionListener 이용 중복 로그인 방지 (0) | 2022.02.17 |
스프링 세션 동작 원리 (0) | 2022.02.17 |
세션 생성 및 제거. (0) | 2022.02.17 |
댓글