Python中如何使用Django实现WebSocket功能

channel 太复杂了,有没有小型一点的非堵塞。
Python中如何使用Django实现WebSocket功能

4 回复

channel 不是很简单么,我照着教程撸的一个服务,跑两年了;偶尔需要重启下


要在Django里搞WebSocket,用channels库是最直接的办法。它让Django能处理WebSocket、HTTP2、聊天协议这些异步协议。下面我给你个完整的例子,从安装到跑起来。

首先,你得装channels

pip install channels["daphne"]

然后改你的Django项目设置。在settings.py里加上:

INSTALLED_APPS = [
    'django.contrib.admin',
    # ... 其他app
    'channels',
]

ASGI_APPLICATION = '你的项目名.asgi.application'

在项目根目录创建或修改asgi.py

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import 你的app名.routing  # 替换成你的app名

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的项目名.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            你的app名.routing.websocket_urlpatterns
        )
    ),
})

在你的app目录下创建routing.py

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/some_path/$', consumers.YourConsumer.as_asgi()),
]

再创建consumers.py来处理WebSocket逻辑:

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class YourConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = "test_room"
        self.room_group_name = f"chat_{self.room_name}"
        
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    async def chat_message(self, event):
        message = event['message']
        await self.send(text_data=json.dumps({
            'message': message
        }))

前端用JavaScript连接:

const socket = new WebSocket('ws://' + window.location.host + '/ws/some_path/');

socket.onmessage = function(e) {
    const data = JSON.parse(e.data);
    console.log('收到消息:', data.message);
};

socket.onopen = function() {
    socket.send(JSON.stringify({
        'message': '你好WebSocket!'
    }));
};

最后用Daphne跑起来:

daphne 你的项目名.asgi:application

核心就是channels接管了Django的请求分发,用ASGI替代WSGI来支持异步协议。记得用异步写法,别阻塞事件循环。

总结:用channels库实现Django WebSocket。

dwebsocket,看着没那么复杂

django3 已经支持 websocket 了。

回到顶部