Stay Hungry,Stay Foolish!

Django Channels -- more than HTTP

Django Channels

Django 仅仅支持 HTTP协议, Channels 扩展了支持的协议类型, 例如 websocket,chat, IoT.

本身实现基于ASGI协议。 但是你也可以选择 同步模式。

 

https://channels.readthedocs.io/en/stable/index.html

Channels is a project that takes Django and extends its abilities beyond HTTP - to handle WebSockets, chat protocols, IoT protocols, and more. It’s built on a Python specification called ASGI.

Channels builds upon the native ASGI support available in Django since v3.0, and provides an implementation itself for Django v2.2. Django still handles traditional HTTP, whilst Channels give you the choice to handle other connections in either a synchronous or asynchronous style.

 

Code Demo

https://github.com/fanqingsong/code_snippet/tree/master/python/django-channel-chat

 

full copied from official tutorial page

https://channels.readthedocs.io/en/stable/tutorial/index.html#

 

key code:

backend

# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    # Receive message from room group
    async def chat_message(self, event):
        message = event['message']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))

 

frontend

<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Chat Room</title>
</head>
<body>
    <textarea id="chat-log" cols="100" rows="20"></textarea><br>
    <input id="chat-message-input" type="text" size="100"><br>
    <input id="chat-message-submit" type="button" value="Send">
    {{ room_name|json_script:"room-name" }}
    <script>
        const roomName = JSON.parse(document.getElementById('room-name').textContent);

        const chatSocket = new WebSocket(
            'ws://'
            + window.location.host
            + '/ws/chat/'
            + roomName
            + '/'
        );

        chatSocket.onmessage = function(e) {
            const data = JSON.parse(e.data);
            document.querySelector('#chat-log').value += (data.message + '\n');
        };

        chatSocket.onclose = function(e) {
            console.error('Chat socket closed unexpectedly');
        };

        document.querySelector('#chat-message-input').focus();
        document.querySelector('#chat-message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // enter, return
                document.querySelector('#chat-message-submit').click();
            }
        };

        document.querySelector('#chat-message-submit').onclick = function(e) {
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            chatSocket.send(JSON.stringify({
                'message': message
            }));
            messageInputDom.value = '';
        };
    </script>
</body>
</html>

 

Upgrade Reference

 

https://github.com/narrowfail/django-channels-chat

A small functional person-to-person message center application built using Django. It has a REST API and uses WebSockets to notify clients of new messages and avoid polling.

 

Architecture

  • When a user logs in, the frontend downloads the user list and opens a Websocket connection to the server (notifications channel).
  • When a user selects another user to chat, the frontend downloads the latest 15 messages (see settings) they've exchanged.
  • When a user sends a message, the frontend sends a POST to the REST API, then Django saves the message and notifies the users involved using the Websocket connection (sends the new message ID).
  • When the frontend receives a new message notification (with the message ID), it performs a GET query to the API to download the received message.

 

 

https://github.com/justdjango/justchat

This tutorial is for how to build a chat application with Django Channels. The tutorial series can be watched here

 

https://github.com/danidee10/Chatire

Real time Chat application built with Vue, Django, RabbitMQ and uWSGI WebSockets Django channels.

 

posted @ 2021-10-20 17:28  lightsong  阅读(84)  评论(0)    收藏  举报
千山鸟飞绝,万径人踪灭