강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của ikarte6668758
ikarte6668758

câu hỏi đã được viết

Xây dựng dịch vụ chat web bằng Python/Django (Feat. Channels) - Phần cơ bản

(Thực hành) Triển khai websocket Echo cực kỳ đơn giản

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

Viết

·

697

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-channelsdjangopython

Câu trả lời 2

3

pyhub님의 프로필 이미지
pyhub
Người chia sẻ kiến thức

안녕하세요.

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()를 불러오는게 맞나요?

pyhub님의 프로필 이미지
pyhub
Người chia sẻ kiến thức

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

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

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

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

image.png

 

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

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

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

 

0

ikarte6668758님의 프로필 이미지
ikarte6668758
Người đặt câu hỏi

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

Hình ảnh hồ sơ của ikarte6668758
ikarte6668758

câu hỏi đã được viết

Đặt câu hỏi