Wordle Maker Project 18일차

PROLCY·2022년 11월 18일
0

Wordle-Maker-Project

목록 보기
18/31

오늘은 11월 18일 18일차이다.

목표

  • 웹소켓 구현

진행

저번에 짰던 웹소켓 실시간 통신 절차를 좀 고쳤다. solver가 단어를 입력하면 POST /solve/:maker/add 요청을 서버에 보내 입력한 단어를 데이터베이스에 등록하게 되는데, 이때 등록 후 solvers 리스트를 데이터베이스에서 뽑아내 바로 socket.io로 보낸다. 그러면 load 페이지에서는 이벤트 리스너가 대기하고 있다가 데이터를 받는 순간 solvers 상태를 업데이트하고, 렌더링해줌으로써 실시간으로 확인할 수 있도록 하였다.

코드

const { Server } = require('socket.io');

module.exports = (server, app) => {
    const io = new Server(server, {
        cors: {
            origin: 'http://localhost:3000'
        }
    });
    app.set('io', io);
    const loader = io.of('/loader');

    loader.on('connection', (socket) => {
        console.log('loader 네임스페이스 접속');
        const maker = socket.handshake.query.maker;
        console.log(maker);
        socket.join(maker);
        
        socket.on('disconnect', () => {
            console.log('loader 네임스페이스 해제');
            socket.leave(maker);
        });
    });
};

서버의 socket.js이다. app.set('io', io)를 통해 라우터에서도 socket.io를 사용할 수 있도록 하였고, loader 네임스페이스를 정의하여 이 네임스페이스 내에서만 통신하도록 하였다. 이때 maker 닉네임에 따라 room들을 따로 분류하여 join 시켰다.

router.post('/:maker/add', async (req, res) => {
    // solver 테이블에 등록
    const solver = await Solver.findOne({
        attributes: ['word_list', 'key_state'],
        where: {
            nickname: req.session.solver[req.params.maker],
            maker: req.params.maker,
        }
    });
    let word_list = JSON.parse(solver.word_list);
    let key_state = JSON.parse(solver.key_state);
    if ( word_list === null )
        word_list = [];
    word_list.push(req.body.newWord);
    key_state = req.body.keyState;

    
    word_list = JSON.stringify(word_list);
    key_state = JSON.stringify(key_state);
    await Solver.update({
        word_list: word_list,
        key_state: key_state,
    }, {
        where: {
            nickname: req.session.solver[req.params.maker],
            maker: req.params.maker,
        }
    });
    req.app.get('io').of('/loader').to(req.params.maker).emit('enter', await getSolvers(req.params.maker));

    console.log(word_list, key_state);
    res.end();
});

POST /solve/:maker/add 요청을 처리하는 라우터이다. 예전이 짜놓은 코드이고, 여기서 추가한 것은 마지막부분에 req.app.get('io')~~ 부분이다. req.app.get('io')는 socket.js에서 등록했던 socket.io를 가져오는 것이고, of('/loader')는 loader 네임스페이스를 의미한다. to(req.params.maker)는 loader 네임스페이스 안에서 maker 닉네임에 따라 분류된 room을 지정해주는 것이고, emit('enter', await getSolvers(req.params.maker))는 enter 이벤트로 solvers 데이터를 보낸다는 의이다.

    const connectSocket = ( makerNickname ) => {
        const socket = io('http://localhost:4000/loader', {
            transports: ['websocket'],
            query: {
                maker: makerNickname,
            }
        });
        socket.on('enter', function(data) {
            console.log(data);
            setSolvers(data);
        });
        return;
    };

클라이언트에서 socket.io에 연결하는 함수이다. makerNickname을 쿼리로 보내서 해당 room에 join하도록 하였고, enter 이벤트 리스너를 달아서 solvers를 업데이트할 수 있도록 하였다.


실시간으로 잘 업데이트되고 있다.

보충할 것

  • socket.io 지식
  • 웹소켓 지식
  • 별개로 서로 다른 maker의 wordle인데도 solver 페이지에서 같은 닉네임을 입력하고 wordle을 풀었을 시 단어가 같이 업데이트되었음. 확인해보니 solver 정보를 업데이트할 때 쿼리에서 maker를 따로 지정해주지 않아서 같은 닉네임끼리 구분하지 못하는 문제가 있었음. 쿼리 조건에 maker 조건을 넣어서 해결

내일 할 것

  • 단어가 아닌 글자 단위로 업데이트

마무리

시간이 좀 걸렸지만 잘 마무리된 것 같다. 그렇지만 뭔가 찜찜한 기분이 든다. 일단 내일과 모레는 알바를 가야하기 때문에 코딩할 시간이 많지 않은데, 최대한 할 수 있는 데까지 해봐야겠다. 웹소켓을 끝내면 아마 실제 배포를 준비해보고 이번 프로젝트를 마무리지을 것 같은데, 더 보충할 내용이 있는지 훑어봐야겠다.

0개의 댓글