해결된 질문
작성
·
547
·
수정됨
0
안녕하세요 제로초님~ 백엔드 개발자 지망생이자 제로초님의 팬인 신유빈입니다.
1개월 가량 하기 문제를 구글링 하며 여러 경우의 수를 찾아보았지만 이유를 찾지 못하여 질문드립니다.
질문드리고자 하는 내용은 이렇습니다.
socket.io 로 이벤트를 emit 할때, 같은 메서드를 사용함에도 객체에 따라 클라이언트에 전송될 때도 있고, 전송되지 않을 때도 있는데 그 원인을 찾지 못하고 있습니다.
현재 저는 신규게시물 혹은 댓글이 작성되었을때 모든 사용자에게 알림을 emit 하고자 합니다.
현재 3가지의 경우 중 A만 성공중인 상태입니다.
A : 테스트를 위하여 handleConnection 메서드에서 소켓에 연결한 사용자의 정보 객체를 message 로 전송시 성공
B : 게시물 작성 시 생성한 알림 메시지 객체를 message 로 전송시 실패
C: 댓글 작성 시 생성한 알림 메시지 객체를 message 로 전송시 실패
모든 케이스에서 클라이언트에게 메시지를 성공적으로 보내려면 어떻게 해야할지 도움을 주실 수 있을까요?
// 실행 동영상
https://youtu.be/AgLmcV53EvM
// 코드
깃허브 저장소 전체 코드
https://github.com/fog-of-war/dev-be/blob/zerocho/README.md
EventsGateway
https://github.com/fog-of-war/dev-be/blob/zerocho/src/events/events.gateway.ts#L55
// fow-be/src/events/events.gateway.ts
/** 웹소켓 연결시 */
handleConnection(@ConnectedSocket() socket: Socket, client: any) {
const interval = setInterval(() => {
const userInfo = socket.userInfo;
this.sendMessage(userInfo);
}, 5000);
socket.on("disconnect", () => {
clearInterval(interval);
});
}
/** 메시지 전송 */
sendMessage(message?: any) {
console.log(" \n 🌠 sendMessage \n", message);
this.server.emit("message", message);
return Promise.resolve("Message sent successfully");
}
AlertService
https://github.com/fog-of-war/dev-be/blob/zerocho/src/alert/alert.service.ts#L12
// fow-be/src/alert/alert.service.ts
// B: 게시물 작성시 실행되는 알림 서비스 코드
async createNotifyAlert(id: number) {
const data = { alert_place_id: id, alert_type: "NOTIFY" as Type };
const alert = await this.prisma.alert.create({ data: data });
const result = await this.makePostAlertMessage(id);
await this.eventsGateway
.sendMessage(result)
.then((response) => {
// console.log("🌠 Notification sent successfully:", response);
})
.catch((error) => {
console.error("🌠 Error sending notification:", error);
// 전송 실패 또는 오류가 발생한 경우에 실행할 로직을 여기에 추가
});
return result;
}
// fow-be/src/alert/alert.service.ts
// C : 댓글 작성시 실행되는 알림 서비스 코드
async createActivityAlert(id: number) {
const data = { alert_comment_id: id, alert_type: "ACTIVITY" as Type };
const alert = await this.prisma.alert.create({ data: data });
const result = await this.makeCommentAlertMessage(id);
await this.eventsGateway
.sendMessage(result)
.then((response) => {
// console.log("🌠 Notification sent successfully:", response);
})
.catch((error) => {
console.error("🌠 Error sending notification:", error);
});
return result;
}
// 출력결과
# A : 클라이언트에 전송 성공
🌠 sendMessage
{
sub: 2,
user_email: 'shin.yubin18@gmail.com',
iat: 1695983169,
exp: 1695986769
}
# B : 클라이언트에 전송 실패
🌠 sendMessage
{
place_id: 1,
place_name: '코엑스',
region_name: '강남구',
post_id: 65,
post_created_at: 2023-09-29T10:27:28.371Z,
post_image_url: 'https://fog-of-war.s3.ap-northeast-2.amazonaws.com/랜드마크/1코엑스.jpeg'
}
# C : 클라이언트에 전송 실패
🌠 sendMessage
{
user_nickname: '구글신유빈',
user_image_url: 'https://fog-of-war.s3.ap-northeast-2.amazonaws.com/defaultProfile.png',
comment_id: 15,
comment_text: '우왕',
comment_created_at: 2023-09-29T10:52:24.960Z
}
답변 3
0
0
연휴중에 답변주셔서 감사합니다.
공유주신 방식으로 socket.broadcast.emit() 진행해보았으나 TypeError: Cannot read properties of undefined (reading 'broadcast') 라는 에러가 발생하네요.
/** 메시지 전송 */
sendMessage(message?: any, @ConnectedSocket() socket?: Socket) {
console.log(" \n 🌠 sendMessage \n", message);
// const stringMessage = JSON.stringify(message);
// console.log(stringMessage);
socket.broadcast.emit("message", message);
return Promise.resolve("Message sent successfully");
}
🌠 sendMessage
{
sub: 2,
user_email: 'shin.yubin18@gmail.com',
iat: 1696039406,
exp: 1696043006
}
{"sub":2,"user_email":"shin.yubin18@gmail.com","iat":1696039406,"exp":1696043006}
/Users/claire/fow/fow-be/src/events/events.gateway.ts:58
socket.broadcast.emit("message", stringMessage);
^
TypeError: Cannot read properties of undefined (reading 'broadcast')
at EventsGateway.sendMessage (/Users/claire/fow/fow-be/src/events/events.gateway.ts:58:12)
at Timeout._onTimeout (/Users/claire/fow/fow-be/src/events/events.gateway.ts:46:12)
at listOnTimeout (node:internal/timers:569:17)
at processTimers (node:internal/timers:512:7)
socket.io의 버전 문제인가 싶어 socket.io@2.0.3 을 설치해보니 하기 오류가 나타나 삭제하였습니다.
src/auth/strategy/ws.strategy.ts:7:16 - error TS2665: Invalid module name in augmentation. Module 'socket.io' resolves to an untyped module at '/Users/claire/fow/fow-be/node_modules/socket.io/lib/index.js', which cannot be augmented.
7 declare module "socket.io" {
https://github.com/socketio/socket.io-redis-adapter/issues/478
https://velog.io/@yeonnex/npm-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%B2%84%EC%A0%84%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1feat.-socket.io%EC%99%80undefined
0
이거 다시 ConnectedSocket 안 쓰던 코드로 되돌려놓으시고 posts.module.ts에서 eventsGateway 빼보세요. 위에 import로 eventsModule했는데 아래에 필요 없을겁니다.
강의에서 eventsGateway 프로바이더로 넣는 실수 하지 말라고 말씀드린 부분입니다.