inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

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

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

705

양념치킨

작성한 질문수 8

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의 헤더처럼 요청 주체를 구별하는 방법이 웹소켓 통신에도 따로 있는건가요?

django-channels django python

답변 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 인스턴스 간에 통신을 하기 위해서는, 강의 뒤에서 다루는 채널 레이어를 사용하게 됩니다.

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

화이팅입니다. :-)

 

0

sunnnwo

안녕하세요,

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

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

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

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

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

1

이진석

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

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

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

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

image.png

 

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

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

0

sunnnwo

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

 

0

양념치킨

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

유저목록 확인 문제 질문드립니다.

0

164

2

안녕하세요 선생님,

0

91

1

하나의 채팅방만 만들어보려고 하는데 잘 안되고 있습니다.

0

103

1

도커와 연동 관련 질문드립니다.

0

205

3

채팅방 참여자 목록 - 채팅방 입장/퇴장 실시간 이벤트 처리

0

165

2

안녕하세요, onopen() 문제로 질문드립니다.

0

137

2

Consumer Instances 관련 질문 있습니다.

0

72

2

안녕하세요, 요청은 채널스에서 먼저 받고, http 요청은 장고를 통해서 처리한다고 하셨는데요.

0

79

2

기능 구현 질문 드립니다.

0

115

1

git에 있는 코드를 다운 받아 실행 해봤는데 에러가 났습니다.

0

153

2

ValueError: No route found for path 'ws/liveblog/'.

0

134

2

지정 경로에 템플릿 파일 만드는 단축키가 뭔가요?

0

121

2

채팅 내역을 영구적으로 저장하고 싶습니다.

0

89

1

질문이 있습니다.

0

164

1

구독 채팅 구현

0

213

1

헷갈려서 질문드립니다.

0

356

2

@login_required 장식자를 적용한후에는 로그인을 성공하면 채팅방으로 어떻게 이동을 하는 건가요?

1

276

1

docker run -d --restart always --name redis7 --publish 6379:6379 redis:7

0

261

1

websocket 자바스크립트 클라이언트 구현?

0

361

1

메세지 리액션 : 좋아요. 질문 드립니다.

0

359

1

{유저명}님이 메세지 입력 중입니다. 메세지 질문드립니다.

0

610

1

채팅 로비에서 유저수 노출을 위하여

0

326

1

채팅방에서 마지막 유저가 나가면 채팅방 자동 삭제 질문드립니다.

0

432

1

동기방식의 consumer 클래스와 비동기방식의 consumer클래스의 차이가 뭔지 궁금합니다.

0

425

1