Inflearn brand logo image

인프런 커뮤니티 질문&답변

김영기님의 프로필 이미지
김영기

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

실시간으로 텍스트, GIF 보내기

12.7.1스스로 해보기 질문되나요

작성

·

37

·

수정됨

0

//채팅창에 현재 참여자 수나 목록표시하기구현한chat.html코드와 socket.j코드입니다. 그런데 chat: ${socket.request.session.color} 이부분이 undefined으로 계속 나옵니다. console.log에 찍어보면 socket.request.session에 color만 빼고 나오네요.

{% extends 'layout.html' %}

{% block content %}
  <h1>{{title}}</h1>
  <a href="/" id="exit-btn">방 나가기</a>
  <fieldset>
  <legend>채팅 내용</legend>
  <div style="display: flex; gap: 20px;">
    <!-- 채팅 목록 -->
    <div id="chat-list" style="flex: 3;">
      {% for chat in chats %}
        {% if chat.user === user %}
          <div class="mine" style="color: {{chat.user}}">
            <div>{{chat.user}}</div>
            {% if chat.gif %}
              <img src="/gif/{{chat.gif}}">
            {% else %}
              <div>{{chat.chat}}</div>
            {% endif %}
          </div>
        {% elif chat.user === 'system' %}
          <div class="system">
            <div>{{chat.chat}}</div>
          </div>
        {% else %}
          <div class="other" style="color: {{chat.user}}">
            <div>{{chat.user}}</div>
            {% if chat.gif %}
              <img src="/gif/{{chat.gif}}">
            {% else %}
              <div>{{chat.chat}}</div>
            {% endif %}
          </div>
        {% endif %}
      {% endfor %}
    </div>

    <!-- 참여자 목록 -->
    <div style="flex: 1;">
      <h3>참여자</h3>
      <ul id="user-list"></ul>
    </div>
  </div>
</fieldset>

  <form action="/chat" id="chat-form" method="post" enctype="multipart/form-data">
    <label for="gif">GIF 올리기</label>
    <input type="file" id="gif" name="gif" accept="image/gif">
    <input type="text" id="chat" name="chat">
    <button type="submit">전송</button>
  </form>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io.connect('http://localhost:8005/chat', {
      path: '/socket.io',
       transports: ['websocket'] 
    });
    socket.emit('join', new URL(location).pathname.split('/').at(-1));
    socket.on('join', function (data) {
      const div = document.createElement('div');
      div.classList.add('system');
      const chat = document.createElement('div');
      chat.textContent = data.chat;
      div.appendChild(chat);
      document.querySelector('#chat-list').appendChild(div);

        if (data.userList) {
    const ul = document.querySelector('#user-list'); // 참여자 목록이 들어갈 ul
    ul.innerHTML = ''; // 기존 목록 초기화
    data.userList.forEach(function (user) {
      const li = document.createElement('li');
      li.textContent = user;
      ul.appendChild(li);  
    });
  }

      
    });
    socket.on('exit', function (data) {
      const div = document.createElement('div');
      div.classList.add('system');
      const chat = document.createElement('div');
      chat.textContent = data.chat;
      div.appendChild(chat);
      document.querySelector('#chat-list').appendChild(div);
    });
    socket.on('chat', function (data) {
      const div = document.createElement('div');
      if (data.user === '{{user}}') {
        div.classList.add('mine');
      } else {
        div.classList.add('other');
      }
      const name = document.createElement('div');
      name.textContent = data.user;
      div.appendChild(name);
      if (data.chat) {
        const chat = document.createElement('div');
        chat.textContent = data.chat;
        div.appendChild(chat);
      } else {
        const gif = document.createElement('img');
        gif.src = '/gif/' + data.gif;
        div.appendChild(gif);
      }
      div.style.color = data.user;
      document.querySelector('#chat-list').appendChild(div);
    });
    document.querySelector('#chat-form').addEventListener('submit', function (e) {
      e.preventDefault();
      if (e.target.chat.value) {
        axios.post('/room/{{room._id}}/chat', {
          chat: this.chat.value,
        })
          .then(() => {
            e.target.chat.value = '';
          })
          .catch((err) => {
            console.error(err);
          });
      }
    });
    document.querySelector('#gif').addEventListener('change', function (e) {
      console.log(e.target.files);
      const formData = new FormData();
      formData.append('gif', e.target.files[0]);
      axios.post('/room/{{room._id}}/gif', formData)
        .then(() => {
          e.target.file = null;
        })
        .catch((err) => {
          console.error(err);
        });
    });
  </script>
{% endblock %}

  const SocketIO = require('socket.io');const { removeRoom } = require('./services'); module.exports = (server, app, sessionMiddleware) => {  const io = SocketIO(server, { path: '/socket.io',transports: ['websocket']  });  app.set('io', io);  const room = io.of('/room');  const chat = io.of('/chat');   const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);  chat.use(wrap(sessionMiddleware));   room.on('connection', (socket) => {    console.log('room 네임스페이스에 접속');    socket.on('disconnect', () => {      console.log('room 네임스페이스 접속 해제');    });  });   chat.on('connection', (socket) => {      console.log('chat 네임스페이스에 접속');      console.log(socket.request.session);    socket.on('join', (roomId) => {      socket.join(roomId);        const room = socket.adapter.rooms.get(roomId); // Set        const userList = room ? Array.from(room) : [];    // 시스템 메시지 + 사용자 목록 전송    socket.to(roomId).emit('join', {      user: 'system',      chat: `${socket.request.session.color}님이 입장하셨습니다.`,      userList,    });  });     socket.on('disconnect', async () => {      console.log('chat 네임스페이스 접속 해제');      const { referer } = socket.request.headers; // 브라우저 주소가 들어있음      const roomId = new URL(referer).pathname.split('/').at(-1);      const currentRoom = chat.adapter.rooms.get(roomId);      const userCount = currentRoom?.size || 0;      if (userCount === 0) { // 유저가 0명이면 방 삭제        await removeRoom(roomId); // 컨트롤러 대신 서비스를 사용        room.emit('removeRoom', roomId);        console.log('방 제거 요청 성공');      } else {        socket.to(roomId).emit('exit', {          user: 'system',          chat: `${socket.request.session.color}님이 퇴장하셨습니다.`,        });      }    });  });}

답변 3

1

김영기님의 프로필 이미지
김영기
질문자

세션 미들웨어 설정했고,세션 저장소 상태 콘솔로확인했고,세션 초기화도했는데,의존성버전도 4.5로 맞춰놧고 근데 아직도 defined이 뜨는데 왜이런거죠, socket.erquest.session은나오는데,socket.request.session.color만 안나옵니다.

0

김영기님의 프로필 이미지
김영기
질문자

  •  

  • 세션 미들웨어 설정했고,세션 저장소 상태 콘솔로확인했고,세션 초기화도했는데,의존성버전도 4.5로 맞춰놧고 근데 아직도 defined이 뜨는데 왜이런거죠, socket.erquest.session은나오는데,socket.request.session.color만 안나옵니다.

    •  

  •  


0

안녕하세요, 인프런 AI 인턴입니다. 김영기님.

req.session.colorundefined로 나오는 문제는 주로 세션 미들웨어 설정과 관련되어 발생할 수 있습니다. 아래에서 몇 가지 주요 점검 사항을 확인해 보세요:

  1. 세션 미들웨어 설정: socket.ioexpress-session을 함께 사용할 때는, 반드시 express-session 미들웨어를 Socket.IO에 바인딩해야 합니다. chat.use(wrap(sessionMiddleware)); 부분이 적절히 설정되어 있어야 합니다. 코드에서 이미 사용하고 있는 wrap은 주로 이 문제를 해결하기 위해 추가됩니다.

  2. 세션 저장소 상태: 세션이 제대로 저장되고 있는지 확인해 보세요. 즉, 세션을 저장하는데 사용하는 저장소(Redis, MongoDB 등)가 잘 동작하고 있는지 또한 확인이 필요합니다.

  3. 세션 초기화: 사용자 요청이 처음 생성될 때 세션이 올바르게 초기화되어야 합니다. 즉, req.session.color를 처음 할당하는 부분이 제대로 동작하고 있는지 확인해 보세요.

  4. 의존성 버전 확인: socket.io 버전과 관련된 문제일 가능성도 있으므로, 강의에 제시된 버전과 충돌 없이 맞게 설정되었는지 확인해 보세요.

아래는 유사한 문제에 대한 해결책을 제공한 기존 답변이니 참고해 보시면 도움이 될 것 같습니다:
- req.session.color를 찾을 수 없다고 나오네요
- 똑같이 했는데 req.session undefined가 뜨네요..

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

김영기님의 프로필 이미지
김영기

작성한 질문수

질문하기