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通信,以便开发出实时聊天、实时游戏等实时应用。