wsServer는 위에서 server.js에서 setUp을 마쳤고, 이제 resolver에서 실제로 구현을 해 봄!!
https://www.apollographql.com/docs/apollo-server/data/subscriptions/
npm install graphql-subscriptions
import { PubSub } from 'graphql-subscriptions'
const pubsub = new PubSub()
export default pubsub
prism처럼 root자리에 pubsub.js를 만들어 아무 subscribe resolver에서 가져다 쓸 수 있게 함.
Subscribe하는 부분, 채팅에서 상대방이 보낸 톡들이 계속 찍힘.
import { gql } from "apollo-server";
export default gql`
type Subscription {
roomUpdates(id:Int!): Message
}
`
root에 constant.js 파일만듬,
export const NEW_MESSAGE = 'NEW_MESSAGE'
publish와 subscribe를 연결해 주는 key같은 것임.
Subscribe하는 부분, 채팅에서 상대방이 보낸 톡들이 계속 찍힘.
이거보다 간단하게 만들 수 있지만, 이중, 삼중으로 방어막 만들어놓음.
import { NEW_MESSAGE } from '../../constants'
import pubsub from '../../pubsub'
import { withFilter } from 'graphql-subscriptions'
import prisma from '../../client'
//import에 NEW_MESSAGE, pubsub, withFilter확인할 것
export default {
Subscription: {
///Mutation 및 Query가 들어가는 자리에 Subscription이 들어감.
roomUpdates: {
subscribe: async (root, args, context, info) => {
//async전에 subscribe를 적어줌.
//arg는 메세지를 실시간으로 받을 roomId 임.
//console.log로 context를 찍어보면, server에서 보낸 loggedInUser가 보임.
console.log(context.id)
const room = await prisma.room.findFirst({
where: {
id: args.id,
users: {
some: {
id: context.id,
},
},
},
select: { id: true },
})
if (!room) {
throw new Error('You shall not see this.')
}
///args와 context를 이용해서 메세지를 실시간으로 받을 room을 찾음.
///room의 id만 select함.
///withFilter를 통해서 subscribe할 조건 및 내용을 만들어줌.
return withFilter(
() => pubsub.asyncIterator(NEW_MESSAGE),
//NEW_MESSAGE key를 넣어줌.
// (payload, variables) => {
// return payload.roomUpdates.roomId === variables.id
// }
//withFilter는 payload, variables 2개의 인자를 받는데
//console로 위 두개를 찍어보면 뭘 받는지 보임.
//밑에서 구현함..
async ({ roomUpdates }, { id }, context) => {
///payload부분에 roomUpdates를 넣어줌,
///roomUpdates는 sendMessage.resolver의 publish부분에서 오는data임
/// id는 roomUpdate의 arg(즉, 메세지 받을 방 id)
/// context는 server.js 에서 보낸 loggedInUser 정보임.
if (roomUpdates.roomId === id) {
//loggedIn User가 방에 있는지
//publish의 roomId와 subscribe의 roomId가 같은지
//디시 한번 더 check해줌
const room = await prisma.room.findFirst({
where: {
id,
users: {
some: {
id: context.id,
},
},
},
select: {
id: true,
},
})
if (!room) {
return false
}
return true
//로직이 끝나고 마지막에 꼭 return true 해줄것!!
}
}
)(root, args, context, info)
//callback Fn이기 떄문에 withFilter()끝나는 부분에
//(root, args, context, info)꼭 넣어 주어야 함.
},
},
},
}
--------------------------------------------------------
// export default {
// Subscription: {
// roomUpdates: {
// subscribe: withFilter(
// () => pubsub.asyncIterator(NEW_MESSAGE),
// (payload, variables) => {
// // console.log(payload, variables)
// return payload.roomUpdates.roomId === variables.id
// }
// ),
// },
// },
// }
~~~~~~~~~~~~~~~~~~~~~~간단하게 subscribe를 구현해 본 code임. 참고하삼!!!