tastekim / WeAllLie-BE

👀We Are Lie는 보드게임 '스파이 폴' 을 모티브로한 화상채팅으로 진행하는 온라인 보드게임 플랫폼 입니다 !(~2022.12.22)
3 stars 4 forks source link

[Error] Https 로 서버 배포 했을 때 소켓 접속 불가 이슈 #103

Closed ghost closed 1 year ago

ghost commented 1 year ago

한 일

:point_down: :point_down: :point_down: :point_down: :point_down:

- app.js

const app = express(); 
const options = {
    ca: fs.readFileSync(`/etc/letsencrypt/live/${process.env.DOMAIN}/fullchain.pem`),
    key: fs.readFileSync(`/etc/letsencrypt/live/${process.env.DOMAIN}/privkey.pem`),
    cert: fs.readFileSync(`/etc/letsencrypt/live/${process.env.DOMAIN}/cert.pem`),
};
const httpsServer = https.createServer(options, app);
module.exports = httpsServer;

- socket.js

const socketIo = require('socket.io');
const httpsServer = require('./app');
const io = socketIo(httpsServer);
io.on('connection', (socket) => {
    console.log('socket.js connected', socket.id);
});
module.exports = io;

- server.js

const httpsServer = require('./src/app');
require('./src/socket');
require('./src/game/game-socket');
require('./src/rooms/room-socket');
require('./src/chat/chat-socket');
httpsServer.listen(process.env.PORT, () => {
    console.log('HTTP 서버가 실행되었습니다. 포트 :: ' + process.env.PORT);
});

에러 내용

조치 사항

환경 설정

OS: ubuntu 20.04.5 LTS
Node:  v16.18.1 
npm : v9.1.2 

@kimhsno1 @tastekim @yunjin5450

ghost commented 1 year ago

추가 조치 1

프록시 패스 설정이 잘못되었을 수도 있다는 말을 듣고 패스 설정 추가해봤으나 여전함. 소켓 접속 시도할 때 도메인 뒤에 :3000 붙여서 접속해봐도 동일한 결과인 것으로 봐서 포트 포워딩의 문제는 아닌 것 같다고 판단.


추가 조치 2

아래와 같이 테스트 서버 파일을 작성해서 실행해 봤습니다. => 한 파일에 서버실행, 소켓 서버 실행 코드를 모아서 작성.

const https = require('https');
const express = require('express');
const fs = require('fs');
const socketIo = require('socket.io');
const app = express();
const cors = require('cors');
require('dotenv').config()

app.get('/', (req, res) => {
    res.send('Hello');
});

const options = {
    ca: fs.readFileSync(
        `/etc/letsencrypt/live/${process.env.DOMAIN}/fullchain.pem`
    ),
    key: fs.readFileSync(
        `/etc/letsencrypt/live/${process.env.DOMAIN}/privkey.pem`
    ),
    cert: fs.readFileSync(
        `/etc/letsencrypt/live/${process.env.DOMAIN}/cert.pem`
    ),
};
const httpsServer = https.createServer(options, app);
httpsServer.listen(3000);
const io = socketIo(httpsServer, cors({ origin: '*' }));

io.on('connection', (socket) => {
    console.log('socket.js connected', socket.id);
});

(결과)

https 서버 배포 자체는 문제가 없는 것 같고 import하는 순서의 문제인 것 같습니다.


추가 조치 3

- chat-socket.js -> chat.on(‘connection’, socket => {}) 내부의 각각의 socket.on 로직들 하나하나를 function 으로 만듦. -> function 예시

    enterLobby(socket) {
        // 로비 입장 메세지
        socket.on('enterLobby', (nickname) => {
            console.log(`${nickname} 로비 입장`);
            const msg = `${nickname} 님이 입장하셨습니다.`;
            const payload = {
                name: nickname,
                msg,
            };
            chat.sockets.emit('receiveLobbyMsg', payload);
        });

-> 각 기능 function들을 ChatSocket이라는 클래스로 합치고, 모듈화하여 내보냄. -> module.exports = new ChatSocket()

- socket.js -> 모듈 임포트 & io 서버 정의

const cors = require('cors');
const socketIo = require('socket.io');
const { httpsServer } = require('./app');
const ChatSocket = require('./chat/chat-socket');

const io = socketIo(httpsServer, cors({ origin: '*' }));

-> chat-socket.js 에서 불러온 메소드들을 io.on(‘connection’, socket => {}) 내부에서 실행되도록 함.

io.on('connection', async (socket) => {
    console.log('socket.js connected', socket.id);
    ChatSocket.enterLobby(socket); 
});

(결과)

  1. 소켓 접속 시 접속 메세지 성공적으로 출력됨
    0|server  | socket.js connected 2FS7MTA4rpVllw7aAAAB
  2. enterLobby 이벤트에 argument 전달하여 실행해보면 minhyeongi.xyz 에 disconnect되어있다는 에러 문구 출력

추가 조치 4

- chat-socket.js -> function으로 분리할 로직을 socket.on(‘enterLobby’, (nickname) => {} 내부의 로직으로 분리 -> function 예시

    enterLobby4(socket, io, nickname, callback) {
        console.log('소켓아이디::::::', socket.id);
        console.log(`${nickname} 로비 입장`);
        const msg = `${nickname} 님이 입장하셨습니다.`;
        const payload = {
            name: nickname,
            msg,
        };
        io.sockets.emit('receiveLobbyMsg', payload);
        callback();
    }

- socket.js -> 모듈 require 부분 동일 -> 실행 코드

io.on('connection', async (socket) => {
    console.log('socket.js connected', socket.id);

    socket.on('enterLobby', async (nickname, callback) => {
        ChatSocket.enterLobby4(socket, io, nickname, callback);
    });
});

-server.js -> 아래 코드만 실행. 이외의 소켓 관련 require 모두 삭제

require('./src/socket');

(결과)

  1. 소켓 접속 시 접속 메세지 성공적으로 출력됨
  2. enterLobby 이벤트에 argument로 닉네임 전달 했을 때, 정상적으로 닉네임과 소켓아이디 출력
    0|server  | socket.js connected qhCRG-Kv359qFbHPAAAB
    0|server  | qhCRG-Kv359qFbHPAAAB
    0|server  | 미뇽 로비 입장
ghost commented 1 year ago

소켓 접속은 되는데 또 갑자기 io.on 내부의 socket.on 함수들을 인식 못하는 문제가 발생해서 해결해보려고 시도하다가 계속 안 돼서 아예 브랜치 새로 파서 다시 전부 수정해보니 갑자기 또 되네요... 이번엔 아예 클래스로 모듈화 하지도 않았는데도 되네요! 도대체 달라진 점이 없는데 이유를 모르겠네요 :sweat_smile: