웹소켓을 활용한 실시간 오목 게임 [현오목]

게임 결과 저장 로직 개발

yebin0322 2025. 1. 9. 23:03
반응형

게임 횟수 DB 저장

user가 둘 다 입장했을 경우만 DB에 저장되어야 하기 때문에 아래 단계를 진행하도록 로직을 생각해 보았다.
1. 현재 로직에서 둘 다 입장하는 것을 판별하는 로직을 찾기
2. DB에서의 게임 횟수(user_game_cnt)를 가져오기
3. 가져온 횟수에 1을 더해서 update하기
4. 1~3이 실행되는 시점은 게임에 입장하고 방에 2명이 다 채워지면 실행되도록 함

1. 방이 2명으로 꽉 찬 시점


위의 사진에서 if문이 true인 시점이다. 그러므로 이 DAO가 실행되는 시점에 가서 로직을 작성해 주어야 한다.

2. DB에 update

처음에는 DB에 저장된 게임 횟수를 가지고 와서 1을 더한 후 update를 해 주려고 했다. 하지만, 그냥 쿼리문 자체에서 1을 더해도 로직이 돌아가기 때문에 좀 더 간단하게 진행할 수 있다.

String query = "update user set user_game_cnt = user_game_cnt + 1 where user_name = ?";
       

다만, 이 때 DAO에서 두 번의 쿼리문이 DB로 넘어간다. 그래서 한 번 connection을 해 준 후, 중괄호 밖으로 나가 새로 쿼리문을 작성한 다음 또 connection을 해 주었다.

이 때, 처음에 로직이 돌아가지 않는 문제점을 발견하였다. 알고 보니 finally 문에서 con.close()를 호출하였기 때문이다. finally 문에서 이미 연결을 끊었기 때문에 연결을 update하더라도 통하지 않는 것이었다. 이후 로직을 전부 실행하고 연결을 끊어주니 잘 돌아갔다.

승, 패가 결정되면 DB에 저장하고 win, lose 표시

우리는 사용자를 웹 소켓으로 구별하였기 때문에, jsp에서 json형식의 message를 받아 원하는 로직을 사용해야 한다.

event값이 state인 경우에는 win,lose에 black, white가 담겨져 전송된다.
DB에는 이긴 횟수만 저장할 것이므로 이기는 경우의 수만 따져주면 된다. '내가 검은 돌이고, 검은 사용자가 이겼을 경우'와, '내가 흰색 돌이고 흰 사용자가 이겼을 경우'만 따져주면 되므로 obj.win == myStoneColor로 if문을 작성하였다.

이 때, jsp의 값을 서블릿으로 넘겨 주는 부분에서 나의 로직에 문제점이 조금 있었다. 처음에는 ajax를 사용하지 않고 하려고 폼태그 등을 활용하려 했었기 때문이다. 하지만, 생각을 해 보니 나는 지금 jsp에서 servlet으로 전송하려는 것이고 그러려면 ajax를 사용해야 한다는 것을 알았다. 이후 ajax를 통해 servlet으로 전송하고, servlet에서 DAO로 전송하니 잘 돌아갔다.

로직을 작성할 때에도 고민이 많았다. 왜냐면 내가 필요로 하는 메소드는 'doGet'인데, 각각의 servlet마다 기능이 있었기 때문이다. 만약 내가 여기에다가 새로운 기능을 추가하여 doGet함수가 두 개의 역할을 하도록 하면 결합도가 높아지기 때문이다.
코드를 작성할 때에는 '낮은 결합도 높은 응집도'가 중요하다. 그래서 나는 WinLoseServlet을 추가로 만들어 게임 결과가 나왔을 때(win, lose가 판별났을 때) /winLose 서블릿을 호출하여 DAO의 updateWinCnt 메소드를 호출하도록 코드를 작성하였다.

import DAO.WinLoseDAO;

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 java.io.IOException;

@WebServlet(name = "winLoseServlet", value = "/winLose")
public class WinLoseServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String loginUser = (String) session.getAttribute("name");
        System.out.println("로그인한 이긴 유저 : " + loginUser);
        WinLoseDAO winLoseDAO = new WinLoseDAO();
        winLoseDAO.updateWinCnt(loginUser);
        doHandle(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doHandle(request, response);
    }

    protected void doHandle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setContentType("text/html; charset=utf-8");
    }
}

spring boot로 프로젝트를 진행할 때에는 api만 만들었기 때문에 백엔드로 정보를 어떻게 전송해 줄 것인지를 고민할 필요가 없었는데, 이번 프로젝트를 진행하면서 정보를 어떤식으로 전송해야 할지를 많이 고민하게 되어서 좋았다. 특히, 그냥 requestParam 식으로 전송할지, json형식으로 전송할지, 그리고 그에 따른 차이점은 무엇인지를 알게 되었다. json방식이 보안성이 훨씬 좋다. 정보를 받아와서 가져다 쓸 때에도 ~.get만 하면 되기 때문에 크게 어려움이 없었다. 이후 메인 프로젝트 때에는 json 형식을 많이 쓸 계획이다.

반응형