강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

양념치킨님의 프로필 이미지
양념치킨

작성한 질문수

파이썬/장고로 웹채팅 서비스 만들기 (Feat. Channels) - 기본편

(실습) 초간단 Echo 웹소켓 구현

웹소켓 동작 방식에 대해 질문이 있습니다.

작성

·

665

0

웹소켓부분은 처음 배워봐서 조금 헷갈리네요 ㅠㅠ

  1. app의 views에서 렌더링 된 echo_page.html은 클라이언트를 의미

  2. 그 클라이언트에서 ws객체를 이용해 여러가지 이벤트 핸들러 처리와 메세지를 웹소켓 서버(ws://localhost:8000/ws/echo/)로 전송할 수 있음

  3. 웹소켓 서버로 전송된 메세지는 routing.py에 등록된 path에 맞게 매칭된 Consumer를 호출

  4. 호출된 Consumer는 receive 오버라이딩을 통해 클라이언트에서 보낸 메세지에 대해 후속 처리

이 프로세스로 흘러가는게 맞나요?

 

한 가지 더 궁금한 점은

이번 예제의 EchoConsumer에서 send로 보낸 메세지는 단순히 '메세지 전송 요청을 보냈던' 클라이언트에게 되돌아가는데 만약 서로 다른 여러 클라이언트에서 요청이 들어오면 각 클라이언트는 어떻게 구별하나요? http의 헤더처럼 요청 주체를 구별하는 방법이 웹소켓 통신에도 따로 있는건가요?

답변 2

3

이진석님의 프로필 이미지
이진석
지식공유자

안녕하세요.

1. app의 views에서 렌더링 된 echo_page.html은 클라이언트를 의미

=> 웹브라우저(클라이언트)가 http://localhost:8000/echo/ 페이지에 접속하면, 이 요청을 echo_page 뷰가 호출되며 처리되고, echo_page.html 을 통해 렌더링된 HTML/JS 응답을 웹브라우저에서 받게 됩니다.

=> 그 HTML/JS 내에는 ws://localhost:8000/ws/echo/ 주소로 웹소켓 접속을 시도하는 코드가 있습니다. 웹브라우저에서는 응답을 받는 즉시, 해당 주소로 웹소켓 연결을 시도하게 됩니다.

=> ws://localhost:8000/ws/echo/ 주소로 웹소켓 요청이 들어가면, /ws/echo/ 주소에 매핑된 EchoConsumer 클래스의 인스턴스가 생성이 되면서, 웹소켓 연결이 맺어집니다. 이 웹소켓 연결이 유지되는 동안에는 그 인스턴스는 계속 유지됩니다.

2. 그 클라이언트에서 ws객체를 이용해 여러가지 이벤트 핸들러 처리와 메세지를 웹소켓 서버(ws://localhost:8000/ws/echo/)로 전송할 수 있음

3. 웹소켓 서버로 전송된 메세지는 routing.py에 등록된 path에 맞게 매칭된 Consumer를 호출

=> ws 객체를 통해서, 연결된 EchoConsumer 인스턴스에게 메세지를 보낼 수 있고 받을 수 있습니다.

4. 호출된 Consumer는 receive 오버라이딩을 통해 클라이언트에서 보낸 메세지에 대해 후속 처리

=> 말씀하신 대로, ws 객체를 통해서 send를 하면, 연결된 EchoConsumer 인스턴스의 receive 메서드가 자동 호출이 됩니다. 메세지 수신에 대한 처리를 하고자한다면, receive 메서드를 재정의(override)해서 구현을 합니다.

---

하나의 Consumer 인스턴스는 단 하나의 웹클라이언트와 연결이 됩니다. 생성된 수많은 Consumer Instance는 서로를 모릅니다. 단지, 연결된 하나의 웹소켓 클라이언트와 통신을 할 뿐이죠.

장고 기본의 CBV에서 각 요청을 처리하는 뷰 클래스의 인스턴스들은 서로를 모르며, 각 요청을 처리하는 것에만 책임이 있는 것과 같습니다.

HTTP 요청을 처리하는 클래스 뷰의 인스턴스는 http 요청을 처리하는 동안에만 살아있으며, 요청 처리가 끝나면 그 인스턴스는 사라집니다.
이와 동일하게 웹소켓 요청을 처리하는 Consumer 인스턴스는 웹소켓 요청을 처리하는 동안에만 살아있으며, 그 연결이 끊어지면 그 인스턴스는 사라집니다. 다만 http에 비해서 웹소켓이 연결이 유지되는 시간이 길어서 조금 더 오래 유지될 뿐입니다.

서로 다른 Consumer 인스턴스 간에 통신을 하기 위해서는, 강의 뒤에서 다루는 채널 레이어를 사용하게 됩니다.

살펴보시고 또 질문 남겨주세요.

화이팅입니다. :-)

 

안녕하세요,

저도 이부분이 헷갈렸는데, 감사합니다.

여기서 추가로 질문이 있는데요,

ws/echo/ 주소에 매핑된 EchoConsumer 클래스의 인스턴스가 생성이 되면서, 웹소켓 연결이 맺어집니다.

이 부분이 html에서 자바스크립트

ws://localhost:8000/ws/echo/ 코드로 웹 소켓 연결 명령을 받은 후 routing.py에 ws/echo/ 주소로 맵핑된 EchoConsumer.as_asgi()를 불러오는게 맞나요?

이진석님의 프로필 이미지
이진석
지식공유자

http 요청에서 urlpatterns의 path에서 주소와 view 함수가 매핑이 되듯이

websocket에서도 path의 주소와 함수가 매핑이 됩니다. 웹소켓 요청이 들어오면 그 함수가 호출이 되어 요청을 처리하는 것이구요.

아래의 채널스 코드에서 확인하실 수 있으시듯이, as_asgi 함수 호출로 인해 app 함수가 생성되고 이를 반환하고 있습니다. 즉 매 웹소켓 연결이 이뤄질 때마다 이 app 함수가 호출이 되어 요청을 처리하게 됩니다.

app 함수 내에서는 consumer 인스턴스를 생성하고 반환토록 구현되어있네요. :-)

image.png

 

살펴보시고 댓글 남겨주세요.

질문에 감사드리고, 새해 복 많이 받으세요. :-)

넵 감사합니다. 선생님께서도 새해 복 많이 받으세요!

 

0

양념치킨님의 프로필 이미지
양념치킨
질문자

상세한 답변 정말 감사합니다! 덕분에 이해가 확실히 됐습니다 ㅎㅎ

양념치킨님의 프로필 이미지
양념치킨

작성한 질문수

질문하기