socket.io 실행
736
1 asked
안녕하세요
채팅을 구현하기위해 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;
Answer 1
0
안녕하세요, 인프런 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 연결 및 데이터 요청을 하시는 것이 좋습니다.
수고하세요!
작업결과물이 수업내용의 화면이 좀 다르네요
0
8
2
강의 도중 에러가 발생합니다.
0
11
2
사진과 같이 영상에 한글이 실시간으로 영어로 번역되어 보입니다
0
5
1
커밋버튼 비활성화
0
11
1
Cursor 질문
0
12
1
웹사이트 구축 질문
0
20
1
플러그인, git repo 설치 및 삭제
0
14
1
162 자료
0
12
2
supabase mcp로 테이블 생성 보여주실떄
0
16
2
addToFile function에서 path를 사용해 새로운 파일을 생성
0
21
1
settings.local.json
0
30
2
강의자료는 어떻게 제작하시나요?
0
20
2
notion 에이전트와 prd-generator 에이전트와의 관계
0
19
2
PRD.md
0
21
2
클로드코드 단축키 문의
0
22
1
Shrimp Task Manager npx 설치 질문
0
26
1
클로드 코드 초기 설정이 안되요
1
25
2
클로드 코드 터미널 텍스트 중복 출력
0
28
2
비밀번호 재설정 1회용 이메일 링크
0
30
1
강의교안
0
40
1
DOCs와 스킬관련 PRD 폴더트리
0
26
2
캡쳐이미지 터미널에 복붙하는 방법 (윈도우 사용시)
0
30
2
강의교안
0
35
2
확장프로그램 찾기
1
34
2

