Comment implémenter des fonctions de communication en temps réel basées sur des WebSockets et des vues asynchrones dans Django

Cet article est partagé par la communauté Huawei Cloud « Un guide complet pour implémenter des fonctions de communication en temps réel à l'aide de WebSockets et de vues asynchrones dans Django » par Lemony Hug.

Dans les applications Web modernes, la communication en temps réel est devenue une fonctionnalité essentielle. Qu'il s'agisse de chat en ligne, de mises à jour de données en temps réel ou de notifications en temps réel, tout cela doit être réalisé grâce à une technologie de communication en temps réel. En tant que framework Web puissant, Django fournit de nombreux outils pour créer différents types d'applications Web. Cependant, en termes de communication en temps réel, le modèle requête-réponse traditionnel ne peut évidemment pas répondre aux besoins. Dans cet article, nous explorerons comment exploiter les WebSockets et les vues asynchrones dans Django pour implémenter des capacités de communication en temps réel.

Introduction aux WebSockets

WebSockets est un protocole qui fournit une communication en duplex intégral sur une seule connexion TCP. Contrairement au modèle requête-réponse HTTP, les WebSockets permettent une communication bidirectionnelle continue entre le serveur et le client, atteignant ainsi le temps réel. Dans Django, nous pouvons utiliser des bibliothèques tierces django-channelspour implémenter la prise en charge de WebSocket.

vue asynchrone

Django 3.1 introduit la prise en charge des vues asynchrones, nous permettant d'écrire des fonctions de vue qui gèrent les requêtes de manière asynchrone. Ceci est utile pour gérer des tâches ou des demandes de longue durée qui nécessitent d'attendre une réponse d'une ressource externe.

Combiner des WebSockets avec des vues asynchrones

Ci-dessous, nous utiliserons un cas pour montrer comment combiner des WebSockets et des vues asynchrones dans Django pour implémenter des fonctions de communication en temps réel. Disons que nous développons une simple application de chat en temps réel.

Installer les dépendances

Tout d'abord, nous devons installer django-channelsla bibliothèque :

canaux d'installation pip

Éléments de configuration

Dans le projet settings.py, ajoutez channelsl'application :

INSTALLED_APPS = [
    ...
    « chaînes »,
    ...
]

Ensuite, créez un routing.pynouveau fichier appelé et définissez-y la route WebSocket :

#routage.py

à partir de canaux.routing importer ProtocolTypeRouter, URLRouter
à partir de canaux.auth importer AuthMiddlewareStack
à partir du chemin d'importation de Django.urls
à partir de myapp.consumers, importez ChatConsumer

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

application = ProtocoleTypeRouter ({
    'websocket' : AuthMiddlewareStack (
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

Créer un consommateur

Ensuite, nous créons un Consumer pour gérer les connexions WebSocket :

# consommateurs.py

importer json
à partir de canaux.generic.websocket importer AsyncWebsocketConsumer

classe ChatConsumer (AsyncWebsocketConsumer) :
    async def connect(soi) :
        self.room_name = 'chat_room'
        self.room_group_name = f'chat_{self.room_name}'

        # Rejoignez le groupe de discussion
        attendre self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        attendre soi.accepter()

    async def déconnecter (self, close_code) :
        # Quitter le groupe de discussion
        attendre self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    réception def asynchrone (self, text_data) :
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Envoyer un message au groupe de discussion
        attendre self.channel_layer.group_send(
            self.room_group_name,
            {
                'type' : 'chat_message',
                'message' : message
            }
        )

    async def chat_message(soi, événement) :
        message = événement['message']

        #Envoyer un message à la connexion WebSocket
        attendre self.send(text_data=json.dumps({
            'message' : message
        }))

Écrire du code frontal

Dans la page front-end, nous devons utiliser JavaScript pour nous connecter à WebSocket et gérer l'envoi et la réception des messages :

// chat.js

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

chatSocket.onmessage = fonction(e) {
    const data = JSON.parse(e.data);
    const message = données['message'];
    // Traite le message reçu
    console.log(message);
} ;

chatSocket.onclose = fonction(e) {
    console.error('Socket de discussion fermé de manière inattendue');
} ;

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

Intégrer dans le modèle

Enfin, nous intégrons le code JavaScript dans le template Django :

<!-- chat.html -->

<!DOCTYPEhtml>
<html>
<tête>
    <titre>Discuter</titre>
</tête>
<corps>
    <textarea id="chat-message-input"></textarea>
    <script src="{% static 'chat.js' %}"></script>
</corps>
</html>

Présentation des vues asynchrones

Avant Django 3.1, les fonctions d'affichage étaient exécutées de manière synchrone, ce qui signifiait que le code d'une fonction d'affichage était exécuté jusqu'à ce qu'une réponse HTTP soit renvoyée au client. Cependant, certaines tâches peuvent prendre du temps, comme appeler des API externes ou effectuer des calculs complexes. Dans ce cas, la synchronisation de la vue bloque l'intégralité de l'application, entraînant une dégradation des performances.

Pour résoudre ce problème, Django a introduit des vues asynchrones, qui utilisent asyncla syntaxe de Python awaitpour prendre en charge les modèles de programmation asynchrone. Les vues asynchrones permettent de suspendre l'exécution pendant le traitement d'une requête, en attendant la fin de l'opération d'E/S sans bloquer l'ensemble de l'application.

Combiner les avantages des WebSockets et des vues asynchrones

La combinaison de WebSockets avec des vues asynchrones peut permettre aux applications de communication en temps réel d'avoir des performances et une évolutivité plus élevées. Lorsqu'un grand nombre de connexions communiquent en même temps, les vues asynchrones peuvent gérer efficacement ces connexions sans affecter le traitement des autres connexions en raison du blocage d'une connexion. De cette façon, l’application peut mieux faire face aux situations de concurrence élevée et maintenir la stabilité et l’efficacité.

Améliorer l'application de chat en temps réel

En plus de la fonctionnalité de chat de base dans l'exemple ci-dessus, nous pouvons également apporter quelques extensions à l'application de chat en temps réel, telles que :

  1. Authentification utilisateur : effectuez l'authentification utilisateur lors de la connexion à WebSocket pour garantir que seuls les utilisateurs connectés peuvent accéder à la salle de discussion.
  2. Gestion des salles de discussion : créez plusieurs salles de discussion et permettez aux utilisateurs de choisir de rejoindre différentes salles de discussion.
  3. Stockage des messages : enregistrez les enregistrements de discussion dans la base de données afin que les utilisateurs puissent afficher l'historique des messages après s'être déconnectés et reconnectés.
  4. Notification de message : implémentez la fonction de notification de message. Lorsque l'utilisateur reçoit un nouveau message, il sera rappelé via une notification du navigateur ou par e-mail.
  5. Liste des utilisateurs en ligne en temps réel : affiche la liste actuelle des utilisateurs en ligne et la met à jour en temps réel lorsque l'utilisateur entre ou quitte la salle de discussion.

Partage de position en temps réel

Supposons que nous développions une application de partage de position en temps réel où les utilisateurs peuvent voir la position d'autres utilisateurs sur une carte en temps réel. Voici un exemple de code simple :

code back-end

# consommateurs.py

importer json
à partir de canaux.generic.websocket importer AsyncWebsocketConsumer

classe LocationConsumer (AsyncWebsocketConsumer) :
    async def connect(soi) :
        self.room_name = 'location_room'
        self.room_group_name = f'location_{self.room_name}'

        # Rejoignez la salle de partage de position
        attendre self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        attendre soi.accepter()

    async def déconnecter (self, close_code) :
        # Quitter la chambre partagée
        attendre self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    réception def asynchrone (self, text_data) :
        text_data_json = json.loads(text_data)
        latitude = text_data_json['latitude']
        longitude = text_data_json['longitude']

        # Envoyer des informations de localisation à la salle partagée de géolocalisation
        attendre self.channel_layer.group_send(
            self.room_group_name,
            {
                'type' : 'location_message',
                'latitude' : latitude,
                'longitude': longitude
            }
        )

    async def location_message (soi, événement):
        latitude = événement['latitude']
        longitude = événement['longitude']

        #Envoyer les informations de localisation à la connexion WebSocket
        attendre self.send(text_data=json.dumps({
            'latitude' : latitude,
            'longitude': longitude
        }))

code frontal

// emplacement.js

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

locationSocket.onmessage = fonction(e) {
    const data = JSON.parse(e.data);
    const latitude = data['latitude'];
    const longitude = données['longitude'];
    //Afficher l'emplacement de l'utilisateur sur la carte
    updateMap(latitude, longitude);
} ;

locationSocket.onclose = fonction(e) {
    console.error('Socket d'emplacement fermé de manière inattendue');
} ;

fonction sendLocation (latitude, longitude) {
    locationSocket.send(JSON.stringify({
        'latitude' : latitude,
        'longitude': longitude
    }));
}

Dans cet exemple, l'utilisateur sélectionne ou déplace un emplacement sur la carte via l'interface frontale, puis envoie les informations de localisation au serveur via WebSocket. Une fois que le serveur a reçu les informations de localisation, il les diffuse à tous les utilisateurs connectés. Une fois que l'interface frontale a reçu les informations de localisation, elle met à jour les emplacements des autres utilisateurs sur la carte en temps réel.

Une telle fonction de partage de localisation en temps réel peut être appliquée dans des applications sociales, des applications de navigation en temps réel et d'autres scénarios pour offrir aux utilisateurs une meilleure expérience interactive.

Visualisation des données en temps réel

Supposons que nous disposions d'un système de surveillance des données qui doit afficher les données de divers capteurs en temps réel. Voici un exemple de code simple :

code back-end

# consommateurs.py

importer json
à partir de canaux.generic.websocket importer AsyncWebsocketConsumer

classe SensorDataConsumer (AsyncWebsocketConsumer) :
    async def connect(soi) :
        self.room_name = 'sensor_data_room'
        self.room_group_name = f'sensor_data_{self.room_name}'

        # Rejoignez la salle de partage de données de capteurs
        attendre self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        attendre soi.accepter()

    async def déconnecter (self, close_code) :
        # Quittez la salle de partage des données des capteurs
        attendre self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    réception def asynchrone (self, text_data) :
        text_data_json = json.loads(text_data)
        sensor_id = text_data_json['sensor_id']
        sensor_value = text_data_json['sensor_value']

        # Envoyer les données du capteur à la salle de partage de données du capteur
        attendre self.channel_layer.group_send(
            self.room_group_name,
            {
                'type' : 'sensor_data_message',
                'sensor_id' : capteur_id,
                'sensor_value' : sensor_value
            }
        )

    async def sensor_data_message (soi, événement):
        sensor_id = événement['sensor_id']
        sensor_value = événement['sensor_value']

        # Envoyer les données du capteur à la connexion WebSocket
        attendre self.send(text_data=json.dumps({
            'sensor_id' : capteur_id,
            'sensor_value' : sensor_value
        }))

code frontal

// capteur_data.js

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

sensorDataSocket.onmessage = fonction(e) {
    const data = JSON.parse(e.data);
    const sensorId = data['sensor_id'];
    const sensorValue = data['sensor_value'];
    // Mettre à jour le graphique des données du capteur
    updateChart(sensorId, sensorValue);
} ;

sensorDataSocket.onclose = fonction(e) {
    console.error('Socket de données du capteur fermé de manière inattendue');
} ;

fonction sendSensorData (sensorId, sensorValue) {
    sensorDataSocket.send(JSON.stringify({
        'sensor_id' : sensorId,
        'sensor_value' : sensorValue
    }));
}

Dans cet exemple, le capteur envoie des données en temps réel au serveur via WebSocket. Une fois que le serveur a reçu les données, il les diffuse à tous les utilisateurs connectés. Une fois que l'interface frontale a reçu les données, elle utilise une bibliothèque de graphiques JavaScript pour. afficher les données en temps réel dans un graphique en temps réel.

Une telle fonction de visualisation des données en temps réel peut être appliquée dans des scénarios tels que la surveillance des données et l'analyse en temps réel, offrant aux utilisateurs des fonctions d'affichage et de surveillance des données en temps réel.

Fonctionnalités avancées et applications avancées

En plus des fonctions de base de chat en temps réel, une série de fonctions avancées et d'applications avancées peuvent être obtenues en combinant WebSockets et vues asynchrones. Voici quelques exemples:

1. Partage de localisation en temps réel

Grâce à WebSocket et aux vues asynchrones, le partage de localisation en temps réel entre les utilisateurs peut être réalisé. Au fur et à mesure que l'utilisateur se déplace, l'application frontale peut envoyer les informations de localisation de l'utilisateur au serveur, qui diffuse ensuite ces informations aux autres utilisateurs. Cette fonction est très utile dans les applications sociales, les applications de navigation cartographique et d'autres scénarios.

2. Visualisation des données en temps réel

Dans le domaine de l'analyse et de la surveillance des données, la visualisation des données en temps réel est une tâche importante. Grâce à WebSocket et aux vues asynchrones, les données peuvent être transmises au front-end en temps réel, et les bibliothèques de graphiques JavaScript (telles que Highcharts, Chart.js, etc.) peuvent être utilisées pour afficher les tendances de modification des données et surveiller l'état du système en temps réel.

3. Édition collaborative en ligne

À l'aide de WebSocket et des vues asynchrones, vous pouvez réaliser des fonctions d'édition collaborative en ligne à plusieurs personnes, similaires à Google Docs. Lorsqu'un utilisateur modifie un document, les autres utilisateurs peuvent voir les modifications apportées au contenu modifié en temps réel, permettant ainsi une édition collaborative en temps réel par plusieurs personnes.

4. Jeux en temps réel

Les jeux en temps réel ont des exigences très élevées en matière de communication en temps réel. La combinaison de WebSocket et de vues asynchrones peut réaliser des jeux en ligne multijoueurs en temps réel, tels que des jeux d'échecs et de cartes, des jeux de stratégie en temps réel, etc., offrant une expérience de jeu fluide.

5. Recherche et filtrage en temps réel

Sur les sites Web et les applications, les utilisateurs peuvent avoir besoin de rechercher et de filtrer des données en temps réel. Grâce à WebSocket et aux vues asynchrones, vous pouvez envoyer des mots-clés de recherche ou des conditions de filtrage au serveur en temps réel, et obtenir les résultats de recherche ou les données filtrées renvoyées par le serveur en temps réel, améliorant ainsi l'expérience utilisateur.

6. Vote et questionnaires en temps réel

Le vote et les questionnaires en ligne nécessitent généralement un accès en temps réel aux résultats du vote ou à l'état de remplissage du questionnaire. En combinant WebSocket et des vues asynchrones, les graphiques des résultats de vote ou les statistiques des questionnaires peuvent être mis à jour en temps réel, permettant aux utilisateurs de comprendre la situation actuelle du vote ou la progression du remplissage du questionnaire en temps réel.

Résumer

Cet article explique comment utiliser les WebSockets et les vues asynchrones dans Django pour implémenter des fonctions de communication en temps réel. Nous avons d'abord découvert les concepts de base et les principes de fonctionnement des WebSockets, ainsi que django-channelscomment utiliser les bibliothèques pour prendre en charge les WebSockets dans Django. Ensuite, nous avons exploré en profondeur le concept et l'utilisation des vues asynchrones, ainsi que la manière de combiner WebSockets et vues asynchrones pour obtenir des fonctions de communication en temps réel.

À travers un exemple simple d'application de chat en temps réel, nous montrons comment créer un consommateur WebSocket (Consumer) pour gérer les connexions WebSocket et utiliser des vues asynchrones pour gérer les événements dans les connexions WebSocket. Nous avons également présenté comment utiliser JavaScript dans la page frontale pour se connecter à WebSocket et traiter les messages reçus en temps réel.

Nous explorons ensuite plus en détail les avantages de la combinaison de WebSockets et de vues asynchrones, et proposons une série de fonctionnalités avancées et des exemples d'applications avancées, notamment le partage de localisation en temps réel, la visualisation de données en temps réel, etc. Ces fonctions et applications peuvent offrir aux développeurs davantage d'innovations et de possibilités pour répondre aux besoins de communication en temps réel dans différents scénarios.

 

Cliquez pour suivre et découvrir les nouvelles technologies de Huawei Cloud dès que possible~

 

Linus a pris sur lui d'empêcher les développeurs du noyau de remplacer les tabulations par des espaces. Son père est l'un des rares dirigeants capables d'écrire du code, son deuxième fils est directeur du département de technologie open source et son plus jeune fils est un noyau open source. contributeur. Robin Li : Le langage naturel deviendra un nouveau langage de programmation universel. Le modèle open source prendra de plus en plus de retard sur Huawei : il faudra 1 an pour migrer complètement 5 000 applications mobiles couramment utilisées vers Java, qui est le langage le plus enclin . vulnérabilités tierces. L'éditeur de texte riche Quill 2.0 a été publié avec des fonctionnalités, une fiabilité et des développeurs. L'expérience a été grandement améliorée. Bien que l'ouverture soit terminée, Meta Llama 3 a été officiellement publié. la source de Laoxiangji n'est pas le code, les raisons derrière cela sont très réconfortantes. Google a annoncé une restructuration à grande échelle.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/u/4526289/blog/11053968
conseillé
Classement