Django Web架构 搭建Websocket服务器(1)
- 文章信息 - Author: 李俊才(jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSite :http://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article: https://blog.csdn.net/qq_28550263/article/details/139129624
HuaWei: https://bbs.huaweicloud.com/blogs/427830
【介绍】:本文介绍在Django中搭建Websocket服务器的最基本知识。
下一节:《 搭建Websocket服务器(进阶篇) 》
目 录
- [1. 概述](#1. 概述)
- [2. 模块的安装和配置](#2. 模块的安装和配置)
-
- [2.1 安装channels库](#2.1 安装channels库)
- [2.2 配置ASGI应用](#2.2 配置ASGI应用)
- [3. asgi.py路由](#3. asgi.py路由)
-
- [3.1 创建ASGI应用文件](#3.1 创建ASGI应用文件)
- [3.2 配置WebSocket路由](#3.2 配置WebSocket路由)
- [4. 创建WebSocket消费者](#4. 创建WebSocket消费者)
- [5. 在前端使用WebSocket与服务器通信](#5. 在前端使用WebSocket与服务器通信)
[1. 概述](#1. 概述)
WebSocket 是一种在单个TCP 连接上进行全双工通信的协议。它最初由HTML5规范提出,旨在解决传统HTTP协议在实时通信方面的不足。与HTTP****不同 ,WebSocket在建立连接后可以保持长连接状态,允许服务器主动向客户端发送数据,而不需要客户端发起请求。
WebSocket通信过程如下:
- 客户端发起一个HTTP 请求,请求头中包含Upgrade: websocket,表示希望将连接升级为WebSocket连接。
- 服务器响应请求,返回状态码101 Switching Protocols,表示同意升级协议。
- 连接升级完成后,客户端和服务器就可以通过这个连接进行全双工通信。
- 在通信过程中,客户端和服务器可以随时向对方发送数据,不受请求-响应模式的限制。
- 当一方关闭连接时,WebSocket连接就会被终止。
WebSocket 使用ws://
(非加密)和wss://
(加密)作为协议前缀,默认端口分别为80
和443
。
WebSocket 特别适合++需要实时交互、频繁通信的应用场景++,例如:
- 聊天应用:
用户可以实时发送和接收消息,无需刷新页面。
服务器可以将新消息实时推送给在线用户。
支持一对一聊天、群聊等多种聊天模式。
- 实时协作工具:
多个用户可以同时编辑同一文档或画板,所有变更实时同步。
用户可以看到其他用户的鼠标位置、选择内容等实时状态。
常见的实时协作工具有在线文档、在线绘图等。
- 在线游戏:
玩家之间可以实时交互,如移动、攻击、聊天等。
服务器可以将游戏状态实时同步给所有玩家。
支持多人在线对战、合作等游戏模式。
- 实时数据更新:
股票行情、汇率、商品价格等实时数据可以通过WebSocket 推送给客户端。
天气预报、新闻推送等实时信息也可以使用WebSocket 及时送达。
客户端无需定时轮询,可以节省带宽和服务器资源。
- 物联网(IoT)应用:
设备可以通过WebSocket 与服务器保持长连接,实时上报数据。
服务器可以实时向设备发送控制指令,如开关灯、调节温度等。
WebSocket可以提供低延迟、高效的设备通信方式。
[2. 模块的安装和配置](#2. 模块的安装和配置)
[2.1 安装channels库](#2.1 安装channels库)
bash
pip install channels
Channels 是一个基于Django 的库,用于处理WebSocket等协议。
[2.2 配置ASGI应用](#2.2 配置ASGI应用)
在settings.py
中添加以下配置:
py
INSTALLED_APPS = [
...
'channels',
]
ASGI_APPLICATION = 'myproject.asgi.application'
[3. asgi.py路由](#3. asgi.py路由)
[3.1 创建ASGI应用文件](#3.1 创建ASGI应用文件)
ASGI (Asynchronous Server Gateway Interface)用于作为服务器网关接口,它是Django Channels 的一部分,用于处理异步请求,包括WebSocket 请求。
在项目根目录下创建asgi.py
文件:
py
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from . import rontings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = ProtocolTypeRouter({
# 这里处理http路由
"http": get_asgi_application(),
# 这里处理WebSocket路由
# rontings.py的websocket_urlpatterns
"websocket": URLRouter(rontings.websocket_urlpatterns),
})
[3.2 配置WebSocket路由](#3.2 配置WebSocket路由)
在项目根目录下创建routing.py
文件:
py
from django.urls import re_path
from my_app1 import consumers
websocket_urlpatterns = [
re_path(r'ws/?p<group>\wt/$', consumers.ChatConsumer.as_asgi()),
]
这里定义的 websocket_urlpatterns 就类似于实现 HTTP 服务器时定义的 urlpatterns ,是对应于WebSocket服务的路由规则。
正则表达式r'ws/?p<group>\wt/$'
用于匹配WebSocket 的URL 。它匹配以ws/
开头,后面跟着一个捕获组group
,最后以/
结尾的URL。捕获组group
可以捕获URL中的一部分,并将其作为参数传递给消费者类。
消费者类consumers.ChatConsumer
(下一个小节会介绍)是我们定义的处理WebSocket 连接和消息的类。通过调用as_asgi()
方法,我们将消费者类转换为ASGI应用,以便在路由中使用。
当一个WebSocket 请求的URL 匹配这个路由规则时,Django Channels 会将请求交给consumers.ChatConsumer
消费者类处理。消费者类可以处理连接的建立、接收消息、发送消息以及连接的关闭等事件。
[4. 创建WebSocket消费者](#4. 创建WebSocket消费者)
WebSocket 中的消费者 ,就类似于HTTP 服务的View
在应用my_app1
创建一个consumers.py
文件,定义WebSocket消费者:
py
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ChatConsumer(WebsocketConsumer):
def websocket_connect(self):
self.accept()
self.send('消息')
def websocket_receive(self, message):
# 客户端基于websocket向后端发送数据时,自动触发接收消息
print(message)
self.send(text_data="收到消息: " + message)
# self.close()
def websocket_disconnect(self, message):
# 客户端与服务器断开连接时,自动触发
print("断开连接")
raise StopConsumer()
[5. 在前端使用WebSocket与服务器通信](#5. 在前端使用WebSocket与服务器通信)
创建WebSocket对象
在前端中,通过JavaScript WebSocket API与服务器建立WebSocket连接,需要先创建一个 WebSocket 对象:
js
const socket = new WebSocket('ws://localhost:8000/ws/chat/');
在上述示例中,ws://localhost:8000/ws/chat/
是服务器的WebSocket地址。ws://
表示使用WebSocket协议,localhost:8000
是服务器的主机和端口,/ws/chat/
是WebSocket的路径。
需要注意的是,WebSocket地址必须以ws://
(非加密)或wss://
(加密)开头,而不是http://
或https://
。并且需要再次强调,WebSocket 是一个独立的基于 TCP 的协议,本身并不是HTTP 。它仅仅是初次握手时使用HTTP,一旦协议升级完成就没什么关系了。
连接建立事件
创建WebSocket对象后,当与服务器的连接成功建立时,会触发onopen
事件。我们可以通过为socket.onopen
属性指定一个函数来处理连接建立的逻辑:
js
socket.onopen = function(event) {
console.log('WebSocket连接已建立');
// 连接建立后的其他逻辑
};
接收消息事件
当服务器向客户端发送消息时,会触发onmessage
事件。我们可以通过为socket.onmessage
属性指定一个函数来处理接收到的消息:
js
socket.onmessage = function(event) {
console.log('收到服务器消息:', event.data);
// 处理接收到的消息
};
在onmessage
事件处理函数中,我们可以通过event.data
获取服务器发送的消息数据,并根据需要进行处理,如更新页面内容、触发特定操作等。
发送消息
要向服务器发送消息,可以使用WebSocket对象的send
方法:
js
function sendMessage(message) {
socket.send(message);
}
在上述示例中,sendMessage
函数接受一个message
参数,表示要发送的消息内容。调用socket.send(message)
即可将消息发送给服务器。
服务器接收到客户端发送的消息后,会在服务器端的相应消费者中触发websocket_receive
方法进行处理。
连接关闭事件
当WebSocket连接被关闭时,会触发onclose
事件。我们可以通过为socket.onclose
属性指定一个函数来处理连接关闭的逻辑:
js
socket.onclose = function(event) {
console.log('WebSocket连接已关闭');
// 连接关闭后的其他逻辑
};
在onclose
事件处理函数中,我们可以执行一些清理操作,如更新连接状态、重新连接等。