- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Redux
- error
- javascript
- 주식차트
- Coin
- 코인차트
- API
- 차트만들기
- nestjs
- 리액트
- graphql
- 항해99
- nextjs
- Firebase
- apollo
- 3주차
- websocket
- 채팅
- Flutter
- 코인
- typescript
- 에러
- 차트구현
- rtk
- 주식
- 차트
- chart
- 비전공자
- react
- typeorm
Act99 기술블로그
[Nextjs] 주식사이트 만들기-7 채팅 프론트엔드 Apollo client - polling & refetch 를 이용한 실시간 채팅 구현 본문
[Nextjs] 주식사이트 만들기-7 채팅 프론트엔드 Apollo client - polling & refetch 를 이용한 실시간 채팅 구현
Act99 2021. 12. 15. 10:07실시간 채팅구현을 Apollo client useQuery 를 이용해 만들 방법을 생각하다가 apollo client docs 에서 polling 과 refetch 개념을 찾았다.
https://www.apollographql.com/docs/react/data/queries/
polling의 경우 타이머 설정 후 타이머 설정 시간마다 실시간으로 refetch를 해주는 기능으로, 쉽게 말해 settimeout 같은 느낌으로 데이터 refetch를 시켜준다.
코드는 다음과 같다.
const { data } = useQuery<frontChatQuery>(GET_CHAT, {
variables: {},
pollInterval: 500,
});
그 결과 실시간 채팅 구현이 잘 된다.
하지만 이것 역시 문제가 있다고 판단되었다.
그건 백엔드에 데이터를 요청하는 수가 너무 많다는 것이다.
가령, 다음 이미지를 보면 이해할 수 있다.
보다시피 채팅 데이터가 업데이트 되지 않았음에도 계속 쿼리를 요청하는 것을 볼 수 있다.
따라서 refetch 를 이용해 사용자가 mutation 을 했을 때, refetch 를 하도록 설정하려고 한다.
useMutation 사용시 query를 refetch 하는 코드는 다음과 같다.
const [createChatMutation, { data: createChatMutationResult, loading }] =
useMutation<frontCreateChatMutation, frontCreateChatMutationVariables>(
CREATE_CHAT,
{
onCompleted,
refetchQueries: [
{
query: GET_CHAT,
},
],
}
);
그 결과
mutation 시 실시간으로 refetch 가 되면서
데이터를 무리하게 요구하지 않고 mutation 시에만 요구하게 된다.
하지만 이 역시 단편적인 면만 봤을 때이다.
이 코드 구현은 결과적으로 사용자 본인이 mutation 을 진행했을 때 그 값을 실시간으로 받아볼 수 있을 뿐이며,
다른 사람들은 새로고침을 하지 않는 이상 이 채팅 내용을 볼 수 없다.
polling과 refetch에 대한 문서들을 보던 중 나와 비슷한 상황을 겪는 사람들을 볼 수 있었다.
polling 의 경우 주기를 짧게하면 서버 과부하가 걸릴 위험이 있고, refetch는 데이터 수신을 할 때 결국 refresh 형태로 이루어져야 하기 때문에 사실상 실시간 구현이 아니라고 한다고 한다.
그리고 대부분 실시간 기능을 구현하는 웹 사이트들은 polling 으로 구현한다고 들었다.
따라서 polling 기능을 이용할 예정이며, 다른 방법을 사용할 수 있는지 꾸준히 찾아볼 예정이다.
- 완성코드
const GET_CHAT = gql`
query frontChatQuery {
chats {
id
createdAt
updatedAt
user
text
}
}
`;
const Chat: React.FC<Props> = ({ width, height }) => {
const [nickname, setNickname] = useState("따끈한 메밀호빵");
const { data } = useQuery<frontChatQuery>(GET_CHAT, {
variables: {},
pollInterval: 500,
});
const { register, handleSubmit, getValues, formState, reset } =
useForm<Inputs>({
defaultValues: { user: nickname },
});
const onCompleted = (data: frontCreateChatMutation) => {
const {
createChat: { ok },
} = data;
if (ok) {
console.log(data);
console.log("Okay! Chat!");
}
};
const [createChatMutation, { data: createChatMutationResult, loading }] =
useMutation<frontCreateChatMutation, frontCreateChatMutationVariables>(
CREATE_CHAT,
{
onCompleted,
// refetchQueries: [
// {
// query: GET_CHAT,
// },
// ],
}
);
const onSubmit: SubmitHandler<Inputs> = () => {
if (!loading) {
const { user, text } = getValues();
createChatMutation({ variables: { createChatDto: { user, text } } });
setNickname(user);
}
};
useEffect(() => {
if (formState.isSubmitSuccessful) {
reset({ user: nickname, text: "" });
}
}, [formState, reset]);
return (
<div
style={{
width: 300,
height: height == undefined ? undefined : height * 0.9,
}}
className=" bg-black flex flex-col justify-center items-center"
>
<div className=" w-72 h-5/6 bg-chartGray-default">
(
<ul>
{data?.chats.map((item: any, index: number) => {
return (
<li key={index} className="flex flex-row">
<h3 className=" mx-2 text-white">{item.id}: </h3>
<h3 className=" mx-2 text-white">{item.user}: </h3>
<h3 className=" text-white">{item.text}</h3>
</li>
);
})}
<li></li>
</ul>
)
</div>
<form className="flex flex-col my-5" onSubmit={handleSubmit(onSubmit)}>
<input
className=" bg-gray-300 mb-2"
{...register("user", { required: true })}
></input>
<input
className=" bg-gray-300 mb-2"
{...register("text", { required: true })}
></input>
<button className=" bg-gray-400" type="submit">
{loading ? "로딩중..." : "전송"}
</button>
</form>
</div>
);
};
export default Chat;
결과
채팅까지 구현되었다.
'개발팁저장소 > nextjs' 카테고리의 다른 글
[Nextjs] 주식사이트 만들기-8 홈 화면 구현 (React table typescript filter search / setGlobalFilter error 해결) (0) | 2021.12.16 |
---|---|
[Nextjs] 주식사이트 만들기-7 윈도우 사이즈 에러 해결 (0) | 2021.12.15 |
[Nextjs] 주식사이트 만들기-6 채팅 프론트엔드 (Websocket Error) (0) | 2021.12.14 |
[Nextjs] 주식사이트 만들기-4 채팅 프론트엔드(Apollo client, graphQL, useQuery) (0) | 2021.12.13 |
[Nextjs] 주식사이트 만들기-3 프론트엔드 채팅 만들기 (Apollo client, graphQL, useForm) (0) | 2021.12.10 |