redux-saga에서 websocket을 이용하기.

이 글은 redux-saga에서 websocket사용을 위해 필요한 사항들을 개인적인 방식으로 정리를 위한 글이므로 참고만 하시길 바랍니다.

 

발단은 이렇습니다.(1차 실패 과정)

react(react-native)에서 socket통신을 위해 websocket을 사용하기로 결정합니다.

- 소켓 통신이 필요한 페이지 로딩마다 websocket을 연결하는 방식을 사용할 수도 있으나, 이렇게 하면 소켓 연결과 종료가 빈번히 발생하여 소켓 연결의 의미가 퇴색되게 느껴집니다. 그리하여 로그인 시에 연결을 하고 로그아웃을 할 때 소켓을 종료시키도록 설계하려 합니다. 물론 소켓 통신이 필요없는 페이지에서도 연결 상태를 유지하므로 서버 리소스가 증가할 수 있다는 점은 염두해 둔 결정입니다.

- 이 방법을 사용하기 위해서는 기존 웹페이지의 방식처럼 페이지마다 document가 있는 방식에서는 까다롭습니다. 하지만 우리는 redux를 사용할 수 있습니다. 페이지 마다의 state가 아닌 redux의 store를 데이터 저장소로 이용하도록 하여 여러 페이지를 이동하더라도 초기화 되지 않는 상태를 가질 수 있습니다. 그래서 redux-saga를 이용하여 소켓 통신을 처리하고자 합니다.

- 구현은 어렵지 않았으나 구현 마무리에 한 가지 문제가 발생합니다. generator로 이루어진 리덕스 사가 프레임 안에서 소켓 이벤트로 가져온 메세지를 핸들링을 일반 콜백함수로 해야하기 때문에 이를 해결하기 위해 문서들을 찾아봅니다. 쉽게 말하면 소켓 이벤트 핸들러 내에서 액션을 디스패지하기 위해서는 제너레이트 함수를 소켓 이벤트 핸들러로 등록해야하는데 이 부분은 분명 문제가 발생할 수 밖에 없습니다. 애초에 이 부분을 생각하지 못한 것에 아직 미천한 실력을 드러냅니다.(소켓 연결과 메세지 핸들링, 모바일 상황에서 인터넷 접속이 재연결 되었을 때 자동 재연결 등은 어렵지 않게 처리가 가능하였지만, 액션 디스패치를 하려고 하니... 이게 아닌듯 싶었습니다.)

 

해결과정

방법은, 우선 제너레이트 함수를 websocket 핸들러로 등록하는 방법이 있다면 간단한데, 그럴 일은 없을 거라 생각합니다.

redux-saga  프레임 안에서 해결하는 방법을 찾던 중 channel을 이용하면 해결이 가능할 것 같습니다.

내가 생각한 핵심은 다음과 같습니다.

- 앞서 실패한 이유에서 이벤트 핸들러 내에서 dispatch를 하는 문제는 해결됩니다.(saga frame내가 아니므로) 그런데 websocket은 양방향 통신을 유지하고 있어야 하기 때문에 특정 컴포넌트에서 연결을 하도록 하면 컴포넌트가 새롭게 mount 될 때 마다 연결이 끊기거나 새롭게 이루어지게 됩니다. 소켓 연결과 종료를 컴포넌트의 상태에 의존하는 방식은 문제가 될 수 밖에 없습니다.

- 따라서 redux-saga 프레임과 외부를 연결하는 방법이 필요합니다. redux-saga의 채널을 사용하면 외부 이벤트와 saga 프레임을 연결할 수 있습니다. 외부 이벤트가 있을 때마다 saga 프레임에 전달을 하도록 할 수 있는 것이죠. 이렇게 하면 소켓을 saga 프레임 외부에 만들어 놓고 소켓 메세지가 도착했을 때 액션을 디스패치 하는 대신 사가 채널로 전달하면 됩니다.

- 채널을 사용하면 이점이 더 있어보입니다. 채널은 buffer라는 개념이 있어서 연속적인 메세지의 전달의 경우 버퍼에 채워진 순서대로 동기적으로 처리할 수 있습니다. 채널을 사용하지 않으면 특정 액션이 동시에 여럿이 디스패치되었을 때 비동기적으로 처리를 하게되므로 순서를 맞출 수 없습니다. 순서를 맞추려고 한다면 buffer가 없기 때문에 각 액션들이 디스패치된 후 처리되기 전까지 block상태로 처리시켜야 하며 처리 도중에 디스패치되는 동일한 액션의 디스패치는 소실될 수 밖에 없습니다.

 

결론은 채널을 사용하면 아주 쉽게 Saga 내에서 socket 양방향 통신을 처리할 수 있다는 이론적인 배경을 정리하였습니다.이젠 실제로 구현을 해보려고 합니다.구현후 정리는 차차 하겠습니다....미완성 

 

 

 

 

'프로그래밍 > React-Native' 카테고리의 다른 글

redux-saga에서 websocket을 이용하기.  (0) 2021.09.25
React Native 워밍업.  (0) 2021.06.20
이 댓글을 비밀 댓글로