详解Django3中直接添加Websockets方式

1. 引言

Django3为我们提供了Channel Layers来支持WebSocket的实时通信。WebSocket和常规的HTTP请求/响应协议不同,不需要客户端发出请求来接收服务端的响应,而是使用HTTP握手后,双方都可以在任意时候主动向对方发送数据。这意味着我们可以实现实时通信的功能,比如在线聊天、实时交互、实时游戏等等。本文将介绍如何在Django3中直接添加WebSocket。

2. 直接添加WebSocket的实现方式

2.1 安装Channel Layers

首先,我们需要安装并配置Channel Layers。Channel Layers提供了信道层的支持,用来进行WebSocket和长轮询请求通信的低级别架构。

我们可以使用ASGI服务器,如daphne或者uvicorn,来运行Channel Layers。这里我们选择daphne。

pip install channels

pip install daphne

2.2 创建项目

接下来,我们创建一个Django 项目:

django-admin startproject websocket_demo

cd websocket_demo

python manage.py migrate

2.3 创建应用程序

创建一个名为websocket_app的应用程序:

python manage.py startapp websocket_app

2.4 编写ASGI应用

接下来,我们需要编写一个ASGI应用,启用Channel Layers。

在项目的根目录下,创建一个名为asgi.py的文件,内容如下:

import os

from django.core.asgi import get_asgi_application

from channels.routing import ProtocolTypeRouter, URLRouter

from django.urls import path

from channels.auth import AuthMiddlewareStack

from . import consumers

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_demo.settings')

application = ProtocolTypeRouter({

"http": get_asgi_application(),

"websocket": AuthMiddlewareStack(

URLRouter([

path("ws/", consumers.ChatConsumer.as_asgi()),

])

),

})

在这里,我们引入了我们的消费者类ChatConsumer,它将在/ ws /下实例化。我们还通过AuthMiddlewareStack添加了身份验证支持。

2.5 添加路由

我们需要将URL转发至asgi,以便让能够触发消费者。所以在websocket_demo项目目录下创建一个urls.py,内容如下:

from django.urls import path

from django.conf.urls import url

from websocket_app.views import *

urlpatterns = [

url(r'^$', index),

path("send_msg/", send_msg, name="send_msg"),

]

同时,我们还需要在websocket_app下的urls.py中添加路由规则来处理对应的请求。所以在websocket_app目录下创建urls.py文件,并添加如下代码:

from django.urls import path

from . import views

urlpatterns = [

path('chat/', views.index),

]

2.6 创建消费者类

接下来,我们需要创建消费者类,用于处理WebSocket连接。

在websocket_app目录下创建名为consumers.py的文件,添加如下代码:

from channels.generic.websocket import AsyncWebsocketConsumer

import json

class ChatConsumer(AsyncWebsocketConsumer):

async def connect(self):

await self.accept()

async def disconnect(self, close_code):

pass

async def receive(self, text_data):

text_data_json = json.loads(text_data)

message = text_data_json['message']

await self.send(text_data=json.dumps({

'message': message

}))

这里我们继承了AsyncWebsocketConsumer类,AsyncWebsocketConsumer类的作用相当于Django视图函数中常用的View类,但AsyncWebsocketConsumer主要用于websocket请求,其中Async表示其为异步处理的意思。

在这里,我们定义了连接的方法accept(),断开连接的方法disconnect()以及接收信息的方法receive()。当有消息接收到时,它会被解析,并原样返回。

2.7 测试

接下来我们启动Consumer服务,使用daphne来启动ASGI应用:

daphne websocket_demo.asgi:application

在浏览器中访问http://localhost:5000/chat/ ,打开控制台查看调试信息,我们就可以看见WebSocket链接已经成功建立了。

运行成功后,我们可以在浏览器中打开控制台,输入以下代码来检查WebSocket连接:

const ws = new WebSocket('ws://localhost:5000/ws/');

ws.onmessage = function(event) {

console.log(event.data);

};

ws.onopen = function(event) {

console.log('WebSocket is connected');

};

如果一切正常,我们将会看到WebSocket连接已经成功建立!

3. 总结

本文介绍了如何在Django3中直接添加WebSocket,使用Channel Layers和ASGI服务器,我们可以非常方便地实现WebSocket通信,以便开发出实时聊天、实时游戏等实时应用。

后端开发标签