ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 게시판 만들기 - 7. 채팅 기능 추가 하기
    JAVA/웹 프로그래밍 - JSP 2020. 11. 28. 18:00

    아래의 내용에 뒤이어 구현해보자.

    designatedroom87.tistory.com/325?category=901206

     

    게시판 만들기 - 6. 게시판의 게시글에 답글 달기

    /board/read_fail.jsp 에 약간의 수정이 발생한다. read_fail.jsp 더보기 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 글 읽기 실패 /board/read.jsp에도 수정을 하..

    designatedroom87.tistory.com

     

    index 파일을 실행하면 header에는 아래와 같이 목록이 뜬다.

    IOT라는 항목을 선택했을 때, 채팅 기능이 나오도록 할 것이다.

    물론 로그인 상태여야 이 채팅 기능을 보여줄 것이고, 그렇지 않으면 로그인 페이지를 보여줄 것이다. 

    채팅 리스트를 구현해보자.

    우선, 

    WEB-INF/common/header.jsp를 수정한다.

    기존의 /iot에서 /iot/index로 변경을 한다.

    즉, iot컨트롤러로 넘겨서 index부분에서 처리를 하도록 한다.

    header.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!--Ctag를 사용하기 위해 추가를 한다. -->
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <div>
    <!--nav 태그에서 메뉴를 만들면 된다.-->
        <nav class="navbar">
            <ul>
                <li><a href="/home/index">홈</a></li>
                <li><a href="/company/index">회사소개</a></li>
                <li><a href="/iot/index">IOT</a></li>
                <li><a href="/board/list">게시판</a></li>
                
                <!--로그인이 된 경우와 아닌 경우 두 경우로 나뉜다. 세션 id가 비어있으면 로그인으로 출력 -->
                <!--로그인/로그아웃을 선택함에 따라 다시  member.controller 패키지의 Controller 서블릿으로 이동 
                	해서 login 혹은 logout을 처리한다.
                -->
                <c:choose>
                <c:when test="${empty sessionScope.id }">
                <li><a href="/member/login">로그인</a></li>
                </c:when>
                <c:otherwise>
                <li><a href="/member/logout">로그아웃[${sessionScope.id}]</a></li>
                </c:otherwise>
                </c:choose>
            </ul>
        </nav>
    </div>

     

    그리고 IOT항목이 선택되면, 이에 대한 모든 처리는 Controller에서 하므로 

    이에 대한 처리를 할 컨트롤러를 하나 만들자.

    src폴더의 하위에 

    iot.controller 패키지를 만들고 Controller.java 를 만든다.

    즉, iot/index로 이동시키자.

    Controller.java

    더보기
    package iot.controller;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import member.model.Member;
    import member.service.MemberService;
    
    //	member로 들어오는 모든 url에 대해서 해당 컨트로럴가 이에 대한 처리를 하겠다는 의미
    @WebServlet("/iot/*")
    public class Controller extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	public void init(ServletConfig config) 
    			throws ServletException {}
    
    	protected void service(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    		
    		//ServletContext application = request.getServletContext();	//	전역 객체
    		
    		//	페이지 페이지 마다 연결 시간 설정 가능. 전역 객체이다.
    		HttpSession session = request.getSession();					 
    		
    		//	1. 페이지를 전송하기 전에 url을 분석하고 분류해서 실행
    		String url = request.getRequestURI();
    		//System.out.println("url : " +url);
    		String contextPath = request.getContextPath();
    		//System.out.println("contextPath : " +contextPath);
    		String path = url.substring(contextPath.length());
    		//System.out.println("path : " +path);
    		String lastPath = url.substring(url.lastIndexOf('/') + 1);	//	마지막 /를 기준으로 분리
    		System.out.println("subPath : " +lastPath);
    		String command = lastPath;
    		
    		//	웹 페이지에서 IOT버튼이 클릭되면
    		if (command.equals("index")) 
    		{
    			//	채팅 페이지로 이동한다.
    			request.setAttribute("page", "chat.jsp");
    		}
    		
    		else
    		{
    			request.setAttribute("page", "index.jsp");
    		}
    		//	2. 분류된 url을 선택하고 전송하는 작업
    		RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/iot/index.jsp");
    				
    		//	3. 페이지로 밀어주는 작업
    		dispatcher.forward(request, response);
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    }

     

    IOT 항목을 처음에 클릭했을 시에, 위의 컨트롤러에서 아래의 if문에서 처리를 하면 된다.

    즉, 이 부분에서는 채팅 리스트를 보여주면 된다.

    이 채팅 리스트를 보여주는 일은 chat.jsp가 할 것이다.

    WEB-INF/iot 폴더에 chat.jsp파일을 만들자.

    chat.jsp에서는 로그인의 유무를 확인하는 작업도 필요하다. 

    만약 로그인 상태가 아니라면, 로그인 페이지로 넘기면 된다.

    이는 member 컨트롤러로 보내면 된다.

    그래서 로그인 상태가 아니면, /member/login으로 넘긴다.

    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" %>
    
    <script>
    	//	소켓 연결을 위해 websocket 객체를 만든다.	 서블릿의 형태로 접속을 한다.
    	var websocket = new WebSocket("ws://localhost:9090/wsocket");
    	
    	var line = 0;
    	
    	//	아래는 웹 소켓에서 사용하는 4가지 이벤트들이다.
    	websocket.onopen = function(message){
    		document.getElementById("state").innerHTML = "소켓 시작"; 
    	}
    	websocket.onclose = function(message){}
    	websocket.onerror = function(message){}
    	//	onmessage는 외부에서 들어온 데이터를 받아서 처리를 하는 이벤트이다.
    	websocket.onmessage = function(message)
    	{
    		//	메시지가 20개이면, 채팅창의 내용을 지운다.
    		if (++line % 20 == 0){
    			line = 0;
    			document.getElementById("chat").value = "";
    		}
    		
    		document.getElementById("chat").value = 
    			document.getElementById("chat").value + "\n" +message.data;
    	}
    	
    	function sendmessage()
    	{
    		//	메시지 박스에 있는 데이터를 전송한다.
    		msg = "[${sessionScope.id}]" + document.getElementById("send").value;
    		websocket.send(msg);
    		
    		//	메시지를 보내고, 메시지 입력 부분을 지워준다. 
    		document.getElementById("send").value = "";
    		/*
    		//	나의 메시지
    		document.getElementById("chat").value = 
    			document.getElementById("chat").value + "\n"+msg; 
    		*/
    	}
    	
    	//	엔터키가 눌리면, 메시지를 전송하는 함수
    	function keypress()
    	{
    		var keycode = event.keyCode;
    		
    		if (keycode == 13)
    			sendmessage();
    	}
    	
    </script>
    
    <!-- 로그인이 되어 있어야 사용 가능 -->
    <c:if test="${empty sessionScope.id}">
    <jsp:forward page="/member/login"></jsp:forward>
    </c:if>
    [${sessionScope.id}]<input id=send type=text size=30>
    <input type=button value="전송" id="button" onclick=sendmessage()>
    
    <p></p>
    <div style="width:100%;height:50%" >
    	<textarea id=chat readonly cols=100 rows=25>
    	
    	</textarea>
    </div>

     

    WEB-INF/iot 폴더에 index.jsp파일을 만들자.

    index.jsp 파일에 body 태그에 아래와 같이 작성된 것을 볼 수 있는데, 이는 키 입력이 가능하도록 하기 위함이다.

    채팅 창에서 글을 입력하고 전송할 때, 엔터 키를 눌러 전송이 가능하도록 구현하려고 하기 위함이다.

    index.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="/css/style.css" rel="stylesheet">
    <script src="/js/jquery-3.5.1.min.js"></script>
    
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
     
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
      
    <title>Insert title here</title>
    </head>
    
    <body onkeypress = "keypress()">
    	<jsp:include page="/WEB-INF/common/header.jsp"></jsp:include>
    	<jsp:include page="/WEB-INF/iot/${page}"></jsp:include>
    	<jsp:include page="/WEB-INF/common/footer.jsp"></jsp:include>
    </body>
    </html>

     

    웹 체팅 기능을 넣기 위해선 아래의 내용을 가지고 와서 약간의 수정을 할 것이다.

    먼저 아래의 내용을 보고 오는 것도 괜찮은 선택이다.

    designatedroom87.tistory.com/323

     

    웹 채팅 만들기

    Dynamic Web Project를 하나 만들자. Dynamic Web Project의 이름은 Chat이라고 하자. 프로젝트를 만드는 자세한 방법과 현재 프로젝트 외의 다른 프로젝트의 서버를 종료하고 현재의 프로젝트 서버만 실행

    designatedroom87.tistory.com

     

    그리고, src폴더의 하위로 socket 패키지를 하나 생성하고 WSocket.java 파일을 만든다.

    WSocket.java

    더보기
    package socket;
    
    import java.util.Collections;
    import java.util.Set;
    
    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;
    
    @ServerEndpoint("/wsocket")
    public class WSocket 
    {
    	private static final Set<Session> sessions = Collections.synchronizedSet(
    			new java.util.HashSet<Session>()
    			);
    	
    	/*
    	//	onopen 이벤트가 호출 되면 실행되는 함수
    	@OnOpen
    	public void handleOpen()
    	{
    		System.out.println("클라이언트가 접속했습니다.");
    	}
    	*/
    	//	onopen 이벤트가 호출 되면 실행되는 함수
    	@OnOpen
    	public void handleOpen(Session session)
    	{
    		System.out.println("클라이언트가 접속했습니다.");
    		System.out.println("session id : " +session.getId());
    		sessions.add(session);
    	}
    	/*
    	//	onclose 이벤트가 호출 되면 실행되는 함수
    	@OnClose
    	public void handleClose()
    	{
    		System.out.println("클라이언트가 연결을 해제했습니다.");
    	}
    	*/
    	//	onclose 이벤트가 호출 되면 실행되는 함수
    	@OnClose
    	public void handleClose(Session session)
    	{
    		System.out.println(session.getId() + "클라이언트가 연결을 해제했습니다.");
    		
    		//	세션을 닫는다.
    		sessions.remove(session);
    	}
    	
    	//	onerror 이벤트가 호출 되면 실행되는 함수
    	@OnError
    	public void handleError(Throwable t)
    	{
    		t.printStackTrace();
    	}
    	/*
    	//	onmessage 이벤트가 호출 되면 실행되는 함수
    	@OnMessage
    	public String handleMessage(String message)
    	{
    		//	서버가 받는다.
    		System.out.println("클라이언트가 보내온 메시지 : ");
    		System.out.println(message);
    		
    		return "메시지 수신 완료";
    	}
    	*/
    	
    	//	onmessage 이벤트가 호출 되면 실행되는 함수
    	@OnMessage
    	public void handleMessage(String message, Session session)
    	{
    		//	서버가 받는다.
    		System.out.println("클라이언트가 보내온 메시지 : ");
    		System.out.println(message);
    		
    		this.sendAll(session, message);
    		
    		try {
    			final Basic basic = session.getBasicRemote();
    			basic.sendText(message);
    		}catch(Exception e) {}
    	}
    	
    	public void sendAll(Session session, String message)
    	{
    		System.out.println(session.getId() + ":" +message);
    		try {
    			int i = 0;
    			//	웹 소켓에 연결되어 있는 모든 아이디를 찾는다.	
    			for (Session s : WSocket.sessions) 
    			{
    				System.out.println(++i);
    				if (!s.getId().equals(session.getId()))
    				{
    					s.getBasicRemote().sendText(message);
    				}
    			}
    		}catch(Exception e) {e.printStackTrace();}
    	}
    }

     

    WebContent폴더에 WebSocketTest.jsp 파일을 만든다.

    아래의 파일은 없어도 된다.

    WebSocketTest.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>WebSocket Basic</title>
    </head>
    
    <body>
    	<h1 id = "state"></h1>
    	<!-- 버튼이 눌리면 웹 소켓을 통해서 전송하는데  sendmessage함수를 이용한다. -->
    	<input id=send type=text><input type="button" value="전송" id="button" onclick=sendmessage()>
    	<script>
    		//	소켓 연결을 위해 websocket 객체를 만든다.	 서블릿의 형태로 접속을 한다.
    		var websocket = new WebSocket("ws://localhost:9090/wsocket");
    		
    		//	아래는 웹 소켓에서 사용하는 4가지 이벤트들이다.
    		websocket.onopen = function(message){
    			document.getElementById("state").innerHTML = "소켓 시작"; 
    		}
    		websocket.onclose = function(message){}
    		websocket.onerror = function(message){}
    		//	onmessage는 외부에서 들어온 데이터를 받아서 처리를 하는 이벤트이다.
    		websocket.onmessage = function(message){
    			document.getElementById("state").innerHTML = message.data; 
    		}
    		
    		function sendmessage()
    		{
    			//	메시지 박스에 있는 데이터를 전송한다.
    			msg = document.getElementById("send").value;
    			websocket.send(msg);
    		}
    	</script>
    </body>
    </html>

     

    만약에 두 대의 컴퓨터가 있다면 두 대의 컴퓨터 모두 실행 중일 때 
    한 쪽 컴퓨터에서 주소창에 localhost 대신에 상대방의 ip주소를 적으면 서로 채팅이 가능하다.

    (같은 네트워크에서는 되는 것을 확인 했다.)

     

    index 파일을 실행해보자. 아래와 같이 입력 창에 글을적고 전송 버튼을 누르거나 엔터 키를 입력하면

    아래와 같이 글이 나온다.

     

     

     

    뒤이어 아래를 구현해보자.

    designatedroom87.tistory.com/329?category=901206

     

    게시판 만들기 - 8. 글 수정 & 글 삭제 구현하기

    아래의 내용에 뒤를 어이 만들어 보자. designatedroom87.tistory.com/326?category=901206 게시판 만들기 - 7. 채팅 기능 추가 하기 index 파일을 실행하면 header에는 아래와 같이 목록이 뜬다. IOT라는 항목을..

    designatedroom87.tistory.com

     

    댓글

Designed by Tistory.