Django에서 WebSocket과 비동기 뷰를 기반으로 실시간 통신 기능을 구현하는 방법

이 기사 는 Lemony Hug가 Huawei 클라우드 커뮤니티에서 공유한 " Django에서 WebSocket 및 비동기 뷰를 사용하여 실시간 통신 기능을 구현하는 완벽한 가이드 "입니다.

최신 웹 애플리케이션에서는 실시간 커뮤니케이션이 필수 기능이 되었습니다. 온라인 채팅, 실시간 데이터 업데이트, 실시간 알림 등 모두 실시간 통신 기술을 통해 구현되어야 합니다. 강력한 웹 프레임워크로서 Django는 다양한 유형의 웹 애플리케이션을 구축하기 위한 많은 도구를 제공합니다. 그러나 실시간 통신 측면에서 전통적인 요청-응답 모델은 분명히 요구 사항을 충족할 수 없습니다. 이 기사에서는 Django에서 WebSocket과 비동기 뷰를 활용하여 실시간 통신 기능을 구현하는 방법을 살펴보겠습니다.

WebSocket 소개

WebSocket은 단일 TCP 연결을 통해 전이중 통신을 제공하는 프로토콜입니다. HTTP 요청-응답 모델과 달리 WebSocket은 서버와 클라이언트 간의 지속적인 양방향 통신을 허용하여 실시간을 달성합니다. Django에서는 타사 라이브러리를 사용하여 django-channelsWebSocket 지원을 구현할 수 있습니다.

비동기식 보기

Django 3.1에서는 비동기식 뷰에 대한 지원을 도입하여 요청을 비동기식으로 처리하는 뷰 함수를 작성할 수 있게 되었습니다. 이는 외부 리소스의 응답을 기다려야 하는 장기 실행 작업이나 요청을 처리하는 데 유용합니다.

WebSocket과 비동기식 뷰 결합

아래에서는 사례를 사용하여 Django에서 WebSocket과 비동기 뷰를 결합하여 실시간 통신 기능을 구현하는 방법을 보여줍니다. 간단한 실시간 채팅 애플리케이션을 개발한다고 가정해 보겠습니다.

종속성 설치

먼저 django-channels라이브러리를 설치해야 합니다.

pip 설치 채널

구성 항목

프로젝트에서 애플리케이션을 settings.py추가합니다 .channels

설치된 앱 = [
    ...
    '채널',
    ...
]

그런 다음, 라는 새 파일을 만들고 routing.py그 안에 WebSocket 경로를 정의합니다.

# 라우팅.py

Channels.routing import ProtocolTypeRouter, URLRouter에서
Channels.auth에서 AuthMiddlewareStack 가져오기
django.urls 가져오기 경로에서
myapp.consumers에서 ChatConsumer 가져오기

websocket_urlpatterns = [
    경로('ws/chat/', ChatConsumer.as_asgi()),
]

애플리케이션 = ProtocolTypeRouter({
    '웹소켓': AuthMiddlewareStack(
        URL라우터(
            websocket_urlpatterns
        )
    ),
})

소비자 생성

다음으로 WebSocket 연결을 처리하기 위한 소비자를 만듭니다.

# 소비자.py

JSON 가져오기
Channels.generic.websocket에서 AsyncWebsocketConsumer 가져오기

클래스 ChatConsumer(AsyncWebsocketConsumer):
    비동기 def 연결(자체):
        self.room_name = '채팅방'
        self.room_group_name = f'chat_{self.room_name}'

        # 채팅방 그룹에 참여하기
        self.channel_layer.group_add를 기다립니다(
            self.room_group_name,
            자체.채널_이름
        )

        self.accept()를 기다립니다.

    비동기 def 연결 해제(self, close_code):
        # 채팅방 그룹에서 나가기
        self.channel_layer.group_discard(
            self.room_group_name,
            자체.채널_이름
        )

    비동기 def 수신(self, text_data):
        text_data_json = json.loads(text_data)
        메시지 = text_data_json['메시지']

        # 채팅방 그룹에 메시지 보내기
        self.channel_layer.group_send(를 기다립니다.
            self.room_group_name,
            {
                '유형': 'chat_message',
                '메시지': 메시지
            }
        )

    비동기 def chat_message(self, 이벤트):
        메시지 = 이벤트['메시지']

        #WebSocket 연결로 메시지 보내기
        self.send(text_data=json.dumps({
            '메시지': 메시지
        }))

프런트엔드 코드 작성

프런트 엔드 페이지에서는 JavaScript를 사용하여 WebSocket에 연결하고 메시지 보내기 및 받기를 처리해야 합니다.

// chat.js

const chatSocket = new WebSocket('ws://localhost:8000/ws/chat/');

chatSocket.onmessage = 함수(e) {
    const 데이터 = JSON.parse(e.data);
    const 메시지 = 데이터['메시지'];
    //받은 메시지를 처리합니다.
    console.log(메시지);
};

chatSocket.onclose = 함수(e) {
    console.error('채팅 소켓이 예기치 않게 닫혔습니다.');
};

document.querySelector('#chat-message-input').addEventListener('keypress', function(e) {
    if (e.key === 'Enter') {
        const messageInputDom = document.querySelector('#chat-message-input');
        const 메시지 = messageInputDom.value;
        chatSocket.send(JSON.stringify({
            '메시지': 메시지
        }));
        messageInputDom.value = '';
    }
});

템플릿에 통합

마지막으로 Django 템플릿에 JavaScript 코드를 통합합니다.

<!-- chat.html -->

<!DOCTYPE HTML>
<html>
<머리>
    <title>채팅</title>
</head>
<본문>
    <textarea id="chat-message-input"></textarea>
    <script src="{% static 'chat.js' %}"></script>
</body>
</html>

비동기식 뷰 소개

Django 3.1 이전에는 뷰 함수가 동기적으로 실행되었습니다. 즉, HTTP 응답이 클라이언트에 반환될 때까지 뷰 함수의 코드가 실행되었습니다. 그러나 외부 API를 호출하거나 복잡한 계산을 수행하는 등 일부 작업에는 시간이 많이 걸릴 수 있습니다. 이 경우 뷰를 동기화하면 전체 애플리케이션이 차단되어 성능 저하가 발생합니다.

이 문제를 해결하기 위해 Django는 Python의 async구문을 사용하여 await비동기 프로그래밍 패턴을 지원하는 비동기 뷰를 도입했습니다. 비동기식 뷰를 사용하면 요청이 처리되는 동안 실행을 일시 중단하고 전체 애플리케이션을 차단하지 않고 IO 작업이 완료될 때까지 기다릴 수 있습니다.

WebSocket과 비동기 뷰의 장점 결합

WebSocket을 비동기식 뷰와 결합하면 실시간 통신 애플리케이션의 성능과 확장성이 향상될 수 있습니다. 동시에 통신하는 연결 수가 많은 경우 비동기식 보기는 하나의 연결 차단으로 인해 다른 연결 처리에 영향을 주지 않고 이러한 연결을 효과적으로 관리할 수 있습니다. 이러한 방식으로 애플리케이션은 높은 동시성 상황에 더 잘 대처하고 안정성과 효율성을 유지할 수 있습니다.

실시간 채팅 애플리케이션 개선

위 예의 기본 채팅 기능 외에도 실시간 채팅 애플리케이션에 다음과 같은 몇 가지 확장을 만들 수도 있습니다.

  1. 사용자 인증: WebSocket에 연결할 때 사용자 인증을 수행하여 로그인한 사용자만 채팅방에 입장할 수 있도록 합니다.
  2. 채팅방 관리: 여러 채팅방을 만들고 사용자가 다른 채팅방에 참여하도록 선택할 수 있습니다.
  3. 메시지 저장: 사용자가 연결을 끊었다가 다시 연결한 후에도 기록 메시지를 볼 수 있도록 채팅 기록을 데이터베이스에 저장합니다.
  4. 메시지 알림: 메시지 알림 기능을 구현합니다. 사용자가 새 메시지를 받으면 브라우저 알림이나 이메일을 통해 사용자에게 알려줍니다.
  5. 실시간 온라인 사용자 목록: 현재 온라인 사용자 목록을 표시하며, 사용자가 채팅방에 입장하거나 나갈 때 실시간으로 업데이트됩니다.

실시간 위치 공유

사용자가 지도에서 다른 사용자의 위치를 ​​실시간으로 볼 수 있는 실시간 위치 공유 애플리케이션을 개발한다고 가정해 보겠습니다. 다음은 간단한 예제 코드입니다:

백엔드 코드

# 소비자.py

JSON 가져오기
Channels.generic.websocket에서 AsyncWebsocketConsumer 가져오기

클래스 LocationConsumer(AsyncWebsocketConsumer):
    비동기 def 연결(자체):
        self.room_name = 'location_room'
        self.room_group_name = f'location_{self.room_name}'

        # 위치 공유방에 참여
        self.channel_layer.group_add를 기다립니다(
            self.room_group_name,
            자체.채널_이름
        )

        self.accept()를 기다립니다.

    비동기 def 연결 해제(self, close_code):
        # 위치공유방 나가기
        self.channel_layer.group_discard(
            self.room_group_name,
            자체.채널_이름
        )

    비동기 def 수신(self, text_data):
        text_data_json = json.loads(text_data)
        위도 = text_data_json['latitude']
        경도 = text_data_json['경도']

        # 지리적 위치 공유방에 위치 정보 전송
        self.channel_layer.group_send(를 기다립니다.
            self.room_group_name,
            {
                '유형': 'location_message',
                '위도': 위도,
                '경도': 경도
            }
        )

    비동기 def location_message(self, 이벤트):
        위도 = 이벤트['위도']
        경도 = 이벤트['경도']

        #WebSocket 연결로 위치 정보 보내기
        self.send(text_data=json.dumps({
            '위도': 위도,
            '경도': 경도
        }))

프런트엔드 코드

// 위치.js

const locationSocket = new WebSocket('ws://localhost:8000/ws/location/');

locationSocket.onmessage = 함수(e) {
    const 데이터 = JSON.parse(e.data);
    const 위도 = 데이터['위도'];
    const 경도 = 데이터['경도'];
    //지도에 사용자 위치 표시
    updateMap(위도, 경도);
};

locationSocket.onclose = 함수(e) {
    console.error('위치 소켓이 예기치 않게 닫혔습니다.');
};

function sendLocation(위도, 경도) {
    locationSocket.send(JSON.stringify({
        '위도': 위도,
        '경도': 경도
    }));
}

이 예에서는 사용자가 프런트 엔드 인터페이스를 통해 지도에서 위치를 선택하거나 이동한 후 WebSocket을 통해 위치 정보를 서버로 보냅니다. 서버는 위치 정보를 수신한 후 이를 연결된 모든 사용자에게 브로드캐스팅합니다. 프런트 엔드 인터페이스는 위치 정보를 수신한 후 지도에서 다른 사용자의 위치를 ​​실시간으로 업데이트합니다.

이러한 실시간 위치 공유 기능은 소셜 애플리케이션, 실시간 내비게이션 애플리케이션 및 기타 시나리오에 적용되어 사용자에게 더 나은 대화형 경험을 제공할 수 있습니다.

실시간 데이터 시각화

다양한 센서의 데이터를 실시간으로 표시해야 하는 데이터 모니터링 시스템이 있다고 가정해 보겠습니다. 다음은 간단한 예제 코드입니다:

백엔드 코드

# 소비자.py

JSON 가져오기
Channels.generic.websocket에서 AsyncWebsocketConsumer 가져오기

클래스 SensorDataConsumer(AsyncWebsocketConsumer):
    비동기 def 연결(자체):
        self.room_name = 'sensor_data_room'
        self.room_group_name = f'sensor_data_{self.room_name}'

        # 센서데이터 공유방에 참여해보세요
        self.channel_layer.group_add를 기다립니다(
            self.room_group_name,
            자체.채널_이름
        )

        self.accept()를 기다립니다.

    비동기 def 연결 해제(self, close_code):
        # 센서데이터 공유실 나가기
        self.channel_layer.group_discard(
            self.room_group_name,
            자체.채널_이름
        )

    비동기 def 수신(self, text_data):
        text_data_json = json.loads(text_data)
        센서 ID = text_data_json['sensor_id']
        센서_값 = text_data_json['센서_값']

        # 센서데이터 공유실로 센서데이터 전송
        self.channel_layer.group_send(를 기다립니다.
            self.room_group_name,
            {
                '유형': 'sensor_data_message',
                '센서_ID': 센서_ID,
                '센서_값': 센서_값
            }
        )

    비동기 def 센서_데이터_메시지(자기, 이벤트):
        센서_ID = 이벤트['센서_ID']
        센서_값 = 이벤트['센서_값']

        # WebSocket 연결로 센서 데이터 보내기
        self.send(text_data=json.dumps({
            '센서_ID': 센서_ID,
            '센서_값': 센서_값
        }))

프런트엔드 코드

// 센서_데이터.js

const sensorDataSocket = new WebSocket('ws://localhost:8000/ws/sensor_data/');

sensorDataSocket.onmessage = 함수(e) {
    const 데이터 = JSON.parse(e.data);
    const 센서Id = 데이터['sensor_id'];
    const 센서값 = 데이터['센서_값'];
    //센서 데이터 차트 업데이트
    updateChart(sensorId, 센서값);
};

sensorDataSocket.onclose = 함수(e) {
    console.error('센서 데이터 소켓이 예기치 않게 닫혔습니다.');
};

함수 sendSensorData(sensorId, 센서값) {
    sensorDataSocket.send(JSON.stringify({
        'sensor_id': 센서 ID,
        '센서_값': 센서값
    }));
}

이 예에서 센서 장치는 WebSocket을 통해 서버에 실시간 데이터를 전송하고, 프런트 엔드 인터페이스는 데이터를 수신한 후 JavaScript 차트 라이브러리를 사용하여 연결된 모든 사용자에게 이를 브로드캐스트합니다. 실시간 데이터를 실시간으로 차트에 표시합니다.

이러한 실시간 데이터 시각화 기능은 데이터 모니터링, 실시간 분석 등의 시나리오에 적용되어 사용자에게 실시간 데이터 표시 및 모니터링 기능을 제공합니다.

고급 기능 및 고급 앱

기본적인 실시간 채팅 기능 외에도 WebSocket과 비동기 뷰를 결합하여 일련의 고급 기능과 고급 애플리케이션을 구현할 수 있습니다. 여기 몇 가지 예가 있어요.

1. 실시간 위치 공유

WebSocket과 비동기식 뷰를 사용하면 사용자 간 실시간 위치 공유가 가능합니다. 사용자가 이동하면 프런트 엔드 응용 프로그램은 사용자의 위치 정보를 서버로 보낼 수 있으며, 서버는 이 정보를 다른 사용자에게 브로드캐스팅합니다. 이 기능은 소셜 애플리케이션, 지도 탐색 애플리케이션 및 기타 시나리오에서 매우 유용합니다.

2. 실시간 데이터 시각화

데이터 분석 및 모니터링 분야에서는 실시간 데이터 시각화가 중요한 작업입니다. WebSocket과 비동기식 뷰를 통해 실시간으로 데이터를 프론트 엔드에 전송할 수 있으며, JavaScript 차트 라이브러리(예: Highcharts, Chart.js 등)를 사용하여 데이터 변화 추세를 표시하고 시스템 상태를 실시간으로 모니터링할 수 있습니다.

3. 온라인 공동 편집

WebSocket 및 비동기식 보기를 사용하면 Google Docs와 유사한 여러 사람의 온라인 공동 편집 기능을 실현할 수 있습니다. 한 사용자가 문서를 편집하면 다른 사용자도 편집 내용의 변경 사항을 실시간으로 확인할 수 있어 여러 사람이 실시간 공동 편집이 가능합니다.

4. 실시간 게임

실시간 게임은 실시간 커뮤니케이션에 대한 수요가 매우 높습니다. WebSocket과 비동기식 뷰를 결합하면 체스 및 카드 게임, 실시간 전략 게임 등과 같은 실시간 멀티플레이어 온라인 게임을 실현하여 원활한 게임 경험을 제공할 수 있습니다.

5. 실시간 검색 및 필터링

웹사이트와 앱 전반에서 사용자는 실시간으로 데이터를 검색하고 필터링해야 할 수도 있습니다. WebSocket과 비동기식 뷰를 통해 검색 키워드나 필터 조건을 실시간으로 서버에 보내고, 서버에서 반환하는 검색 결과나 필터링된 데이터를 실시간으로 받아 사용자 경험을 향상시킬 수 있습니다.

6. 실시간 투표 및 설문조사

온라인 투표 및 설문조사에는 일반적으로 투표 결과나 설문지 작성 상태에 대한 실시간 액세스가 필요합니다. WebSocket과 비동기 뷰를 결합하면 투표 결과 차트나 설문지 통계가 실시간으로 업데이트되므로 사용자는 현재 투표 상황이나 설문지 작성 진행 상황을 실시간으로 이해할 수 있습니다.

요약하다

이 기사에서는 Django에서 WebSocket과 비동기 뷰를 사용하여 실시간 통신 기능을 구현하는 방법을 소개합니다. 먼저 WebSocket의 기본 개념과 작동 원리, 그리고 django-channelsDjango에서 라이브러리를 사용하여 WebSocket을 지원하는 방법을 배웠습니다. 다음으로 비동기 뷰의 개념과 사용법, 그리고 WebSocket과 비동기 뷰를 결합하여 실시간 통신 기능을 구현하는 방법을 자세히 살펴보았습니다.

간단한 실시간 채팅 애플리케이션 예제를 통해 WebSocket 소비자(Consumer)를 생성하여 WebSocket 연결을 처리하고 비동기 뷰를 사용하여 WebSocket 연결의 이벤트를 처리하는 방법을 보여줍니다. 또한 프런트엔드 페이지에서 JavaScript를 사용하여 WebSocket에 연결하고 수신된 메시지를 실시간으로 처리하는 방법도 소개했습니다.

그런 다음 WebSocket과 비동기식 뷰 결합의 이점을 자세히 살펴보고 실시간 위치 공유, 실시간 데이터 시각화 등을 포함한 일련의 고급 기능과 고급 애플리케이션의 예를 제공합니다. 이러한 기능과 애플리케이션은 개발자에게 다양한 시나리오에서 실시간 통신 요구 사항을 충족할 수 있는 더 많은 혁신과 가능성을 제공할 수 있습니다.

 

화웨이 클라우드의 신기술에 대해 빨리 알아보고 팔로우하려면 클릭하세요~

 

Linus는 커널 개발자가 탭을 공백으로 대체하는 것을 막기 위해 스스로 노력했습니다. 그의 아버지는 코드를 작성할 수 있는 몇 안되는 리더 중 한 명이고, 둘째 아들은 오픈 소스 기술 부서의 책임자이며, 막내 아들은 오픈 소스 코어입니다. 기고자 Robin Li: 자연 언어 새로운 범용 프로그래밍 언어가 될 것입니다. 오픈 소스 모델은 Huawei에 비해 점점 더 뒤쳐질 것입니다 . 일반적으로 사용되는 5,000개의 모바일 애플리케이션을 Hongmeng으로 완전히 마이그레이션하는 데 1년이 걸릴 것입니다. 타사 취약점. 기능, 안정성 및 개발자의 경험이 크게 개선된 Quill 2.0 출시되었습니다. Ma Huateng과 Zhou Hongyi는 "원한을 제거하기 위해" 공식적으로 출시되었습니다. Laoxiangji의 소스는 코드가 아닙니다. Google이 대규모 구조 조정을 발표한 이유는 매우 훈훈합니다.
{{o.이름}}
{{이름}}

추천

출처my.oschina.net/u/4526289/blog/11053968