inflearn logo
강의

講義

知識共有

socket.io 실행

736

bin

投稿した質問数 1

0

안녕하세요

채팅을 구현하기위해 socket.io를 썼는데 통신이 안되는 것같습니다 io에 주소를 제대로 넣었고 서버 on 마다 클라이언트에서 emit으로 작성했는데 작동하지 않습니다 이유가 무엇일까요?

 

// server 파일의 코드입니다

 

require('dotenv').config();

const { createApp } = require('./app');
const { appDataSource } = require('./models/index');

const startServer = async () => {
 const app = createApp();
const PORT = process.env.PORT;
 await appDataSource
 .initialize()
 .then(() => {
  const server = app.listen(PORT, () => {
   console.log(`🟢server is listening on ${PORT}🟢`);
    });
const io = require('socket.io')(server, {
cors: {
 origin: true,
 credentials: true,
},
  });
 const { socketMessage } = require('./middlewares/socket.io');
 socketMessage(io);
    })
.catch((err) => {
console.log(`❌Failed server connect❌`);
appDataSource.destroy();
});
};
startServer();

 

// server의 socket 파일의 코드입니다

 

const jwt = require('jsonwebtoken');
const chatDao = require('../models/chatDao');

const { catchAsync } = require('../utils/error');

const socketMessage = (io) => {
io.use((socket, next) => {

    const token = socket.handshake.headers.authorization;

    if (!token) {

      return next(new Error('Authentication error'));

    }

    jwt.verify(token, process.env.SECRET_KEY, async (err, decoded) => {

      if (err) {

        return next(new Error('Authentication error'));

      }
      userId = decoded.userId;

      next();

    });

  });

  io.on('connection', (socket) => {

    console.log('A User Connected.');

    socket.on(

      'create_room',

      catchAsync(async (postId, callback) => {

        const room = await chatDao.createRoom(userId, postId);

        socket.join(room.raw.insertId);

        callback(room.raw.insertId);

      })

    );
 socket.on(

      'enter_room',

      catchAsync(async (roomId, callback) => {

        socket.join(roomId);

        callback(roomId);

      })

    );


    socket.on('new_text', async (content, roomId, callback) => {

      await chatDao.createChat(userId, content, roomId);

      socket.to(roomId).emit('new_text', content);

      callback(content);

    });


    socket.on('disconnect', () => {

      console.log('접속이 해제되었습니다', socket.id);

      clearInterval(socket.interval);

    });


    socket.on('error', (error) => {

      console.error(error);

    });
​

    socket.on('send', (data) => {

      console.log(data);

      socket.emit('reply', {

        data,

      });

    });


    socket.interval = setInterval(() => {

      socket.emit('news', 'Hello Socket.IO');

    }, process.env.SOCKET_INTERVAL || 1000);

  });

};


module.exports = { socketMessage };
​

 

// client 코드입니다

import React, { useState, useContext } from 'react'; import io from 'socket.io-client';
import './chat.css'; import { MenuContext } from '../../components/Nav/MenuProvider'; 

const Token = localStorage.getItem('accessToken');

const socket = io.connect('http://192.168.0.194:4000', { 
withCredentials: true,
extraHeaders: {Authorization: `Bearer ${Token}`
}
appDataSource.destroy();
}),
});

socket.on('connection', () => { console.log('Connected to server'); 
});

const Chat = () => {   const [roomId, setRoomId] = useState([]);

const [searchData, setSearchData] = useContext(MenuContext);

const handleCreateRoom = event => { 
event.preventDefault(); 
socket.emit('create_room', searchData, ({ searchData, roomId }) => { 
console.log(`Joined room ${roomId}`);
setRoomId(roomId);
});
};

const handleJoinRoom = roomId => { socket.emit('enter_room', roomId, roomId => { console.log(`Joined room ${roomId}`);
setRoomId(roomId);

});

};

const handleNewText = content => { socket.emit('new_text', content, roomId, content => { console.log(`Sent message: ${content}`);

});

};

const handleNewText = content => {

socket.emit('new_text', content, roomId, content => {       console.log(`Sent message: ${content}`);

});

};

const onCheckEnter = e => {if (e.key === 'Enter') {

handleNewText();

}

};

return (

<div className="h-screen pt-36">

<button onClick={handleCreateRoom}>테스트</button>

<button onClick={() => handleJoinRoom(roomId)}>테스트2</button>

<input id="input-text" type="text" onKeyDown={onCheckEnter} />

<button onClick={handleCreateRoom}>제출</button>

</div>

);

};

export default Chat; 

react javascript socket socket.io node.js

回答 1

0

communityai8509

안녕하세요, 인프런 AI 인턴이에요.

코드를 보니 서버와 클라이언트 모두 문제가 없어보입니다. 가능성이 있다면 .env 파일에서 PORT와 SECRET_KEY의 값을 정확하게 설정했는지 확인해보시는 것이 좋을 것 같아요.

그리고 client 코드에서 아래 코드 중 appDataSource.destroy() 코드는 삭제하셔야 합니다. 여기는 server에서 initialize하고 실행하는 부분이기 때문에, client에서는 필요하지 않습니다.

const socket = io.connect(’http://192.168.0.194:4000’, {
withCredentials: true,
extraHeaders: {Authorization: Bearer ${Token}}
// appDataSource.destroy(), // 삭제!
});

일단 처음 추측하는 문제는 서버와 클라이언트 사이에 CORS (Cross-Origin Resource Sharing) 문제가 있을 수 있다는 것입니다. 서버 코드 중, socket.io 서버를 생성할 때 cors 옵션을 사용하고 있지만, client에서는 cors 설정을 하지 않았습니다. 따라서, client 코드에 cors 옵션을 추가하시면 더 매끄러운 연결이 가능할 것 같습니다.

const socket = io.connect(’http://192.168.0.194:4000’, {
withCredentials: true,
extraHeaders: {Authorization: Bearer ${Token}},
cors: {
origin: true,
credentials: true,
},
});

위와 같이 client 코드에 cors 옵션을 추가해보시기 바랍니다. 혹시 해결이 안된다면 error 이벤트를 잡아서 해당 이벤트에서 어떤 에러가 발생하는지 확인해보시는 것도 좋을 것 같습니다.

그리고 서버 실행 후 바로 client에서 접속하시면 제대로 타이밍이 안맞을 수 있어요. 만약 socket.io 서버에 의해 생성된 “connection” 이벤트에 기능을 추가해놓았다면, client에서 connect 이벤트 이후에 실행해야 멀티 사용자 기반 추적이 가능해요. 기존에 emit 함수를 사용하는 connect 이벤트는 보안과 성능 문제 때문에 권장되지 않습니다. connect 이벤트 대신, DOM이 렌더링 된 후 useEffect 함수를 통해 socket 연결 및 데이터 요청을 하시는 것이 좋습니다.

수고하세요!

(VS코드) install command 아무리 해도 안나옵니다

0

9

1

강의 수강 후 포트폴리오 준비 방향에 대해 조언 부탁드립니다.

1

11

1

@/styles/globals.css'

0

14

2

VS Code의 Command pallet에서 'install command'해도 'code' command가 안보입니다.

0

21

1

용어 발음법이 계속 바뀌는 것 같은데 이런 부분들 개선이 가능할까요...?

0

17

1

파일 디렉토리 구조가 다르네요

0

20

1

클로드 초기설정

0

24

1

슬슬 따라하기가 힘들어진다.

0

61

2

counter01.html은 어디있을까요?

1

16

1

[문의] 섹션 7 미션 진행 중...

0

27

2

기본 브랜치의 이름이 master에요.

0

38

2

관리자 페이지 질문

0

20

1

plans 생성이 안됩니다.

0

34

3

더빙에 어떤 ai가 쓰였는지 궁금합니다.

0

41

2

보안 적용에 대한 강의가 있을까요?

0

28

2

Auto-memory 기능

0

28

2

64강 context 7 관련 질문

0

31

2

Auto-memory 기능

0

26

1

55강 7분56초

0

24

1

55강 git 초기화 관련 질문이요

0

28

2

클로드 코드에 붙여넣기후 편집 관련 질문입니다!

0

30

2

존재하지 않는 일기 url입력 시 alert이 두 번 떠요

0

32

1

윈 터미널의 클로드와 에디터의 터미널의 클로드에 관한 질문

0

18

2

output-styles 명령어 없어 지지 않았나요?

0

27

2