django ASGI/Channels 启动和 ASGI/daphne的区别
Django ASGI/Channels 是 Django 框架的一个扩展,它提供了异步服务器网关接口(ASGI)协议的支持,以便处理实时应用程序的并发连接。ASGI 是一个用于构建异步 Web 服务器和应用程序的规范。
在以前的版本中,Django 使用的是 WSGI(Web 服务器网关接口)协议,该协议是一种同步的协议,只能处理一个请求-响应周期。这意味着在处理长轮询、WebSocket 及其他类似的实时应用程序时,传统的 Django 无法提供良好的性能和扩展性。
与传统的 Django 不同,使用 Django ASGI/Channels 可以构建具有实时功能的异步应用程序,例如聊天应用、通知系统等。Channels 提供了一个消息队列来处理异步任务,并且可以与 WebSocket、长轮询等技术结合使用。
ASGI/daphne 是一个符合 ASGI 规范的异步 Web 服务器,能够处理 ASGI 应用程序的并发连接。它是 Channels 官方推荐的生产级服务器,并提供高性能和可靠的连接管理。你可以将 ASGI/daphne 与 Django ASGI/Channels 一起使用,以部署具有实时功能的 Django 应用程序。
总结来说,Django ASGI/Channels 是 Django 的一个扩展,使其能够处理实时应用程序的并发连接。而 ASGI/daphne 则是一个符合 ASGI 规范的异步 Web 服务器,用于处理 ASGI 应用程序的并发连接。两者结合使用可以构建高性能、具有实时功能的 Django 应用程序。
文件类比
daphne 启动命令
daphne 你的工程项目名称.asgi:application
python本身只支持http协议 使用websocket需要下载第三方库
pip install -U channels
需要在seting.py里配置,将我们的channels加入INSTALLED_APP里。
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
...
'channels',
)
尾行添加
ASGI_APPLICATION = 'bug_Project_name.asgi.application'
修改asgi.py文件
import os
from channels.routing import ProtocolTypeRouter,URLRouter
from django.core.asgi import get_asgi_application
from . import routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bug_Project2.settings')
#application = get_asgi_application()
application = ProtocolTypeRouter({
"http":get_asgi_application(),
"websocket":URLRouter(routing.websoctet_urlpatterns )
})
在settings.py的同级目录创建routing.py
from django.urls import re_path
from web import consumerswebsoctet_urlpatterns = [
re_path('ws/(?P<group>\w+)/$',consumers.ChatConsumer.as_asgi()),
]
在web.views中创建consumers.py
# -*- coding:UTF-8 -*-
# author:Administrator
# contact: 913632472@qq.com
# datetime:2022/1/10 11:55
# software: PyCharm"""
文件说明:
"""from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumerclass ChatConsumer(WebsocketConsumer):
def websocket_connect(self,message):
# 有客户端来向后端发送websocket连接请求时,自动触发
# 后端允许客户端创建连接
print('有人来了')
self.accept()
#给客户端发送小时
self.send("欢迎啊")def websocket_receive(self, message):
# 浏览器基于websocket向后端发送数据,自动触发接受消息
text = message['text']
print("接受到消息-->", text)
res = "{}SB".format(text)
if text == "关闭":
# 客户端通过发送命令 主动断开连接
self.close()
print('通过命令关闭')
raise StopConsumer # 如果服务端断开连接,执行StopConsumer异常 那么websocket_disconnect不会执行
self.send(res)
# self.close() #后端主动断开websocket
def websocket_disconnect(self, message):
# 客户端与服务端断开连接,自动触发
print("客户端断开连接")
raise StopConsumer
django中需要了解的
- wsgi,只支持http请求
- asgi,wsgi+异步+websockt
settings.py的installed_apps中的首行
简单使用前端页面测试websocket
<html lang="en">
<head>
<meta charset="UTF-16">
<title>title</title>
<style>
.message{
height: 300px;
border: 1px solid #dddddd;
width: 100%;
}
</style>
</head>
</html>
<div class="message" id="message"></div>
<div>
<input type="text" placeholder="请输入" id="txt">
<input type="button" value="发送" οnclick="sendMessage()">
</div><script>
socket = new WebSocket("ws://127.0.0.1:8000/room/123/")
//创建好连接后触发
socket.onopen = function (event) {
let tag = document.createElement("div");
tag.innerText = "[连接成功]";
document.getElementById("message").appendChild(tag);}
//当websocket接受要服务端发来的信息 会自动触发这个函数
socket.onmessage = function (event){
let tag = document.createElement("div");
tag.innerText = event.data;
document.getElementById("message").appendChild(tag);
}function sendMessage(){
let tag = document.getElementById("txt");
socket.send(tag.value);
}function closeConn() {
socket.close(); //服务端发送断开请求}
</script>
websocket介绍:
channels 4.0之后默认不带Daphne服务器了。
解决方案可以有两种:
1.指定channels的版本为3.x;
2.安装时使用pip3 install -U channels[“daphne”]
当前问题不管高版本还是低版本 老是报如下问题
之后找到老师获取课程中的源代码 笔者使用教程中的代码跑通了
还是回到这个问题
这个坑废了我2天时间
ValueError: No application configured for scope type 'websocket'
经过课程中的代码和笔者的代码来回对比 多次测试
这里应该是websocket 而缺少了e字母 应该是写项目的时候复制csdn参考源码 网友留的坑
而后将项目依赖全部升级为最新版本 完全可以跑通!
效果图
小结
基于django实现websocket请求 但只能对某个人进行处理
群聊(二)
基于channels中提供channel layers来实现。
-
setting中配置。
CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer", } }
pip3 install channels-redis
CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [('10.211.55.25', 6379)] }, }, }
-
consumers中特殊的代码。
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer from asgiref.sync import async_to_sync class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): # 接收这个客户端的连接 self.accept() # 获取群号,获取路由匹配中的 group = self.scope['url_route']['kwargs'].get("group") # 将这个客户端的连接对象加入到某个地方(内存 or redis) async_to_sync(self.channel_layer.group_add)(group, self.channel_name) def websocket_receive(self, message): group = self.scope['url_route']['kwargs'].get("group") # 通知组内的所有客户端,执行 xx_oo 方法,在此方法中自己可以去定义任意的功能。 async_to_sync(self.channel_layer.group_send)(group, {"type": "xx.oo", 'message': message}) def xx_oo(self, event): text = event['message']['text'] self.send(text) def websocket_disconnect(self, message): group = self.scope['url_route']['kwargs'].get("group") async_to_sync(self.channel_layer.group_discard)(group, self.channel_name) raise StopConsumer()
总结
b站演示地址 https://b23.tv/UZvBFy3
-
websocket是什么?协议。
-
django中实现websocket,channels组件。
-
单独连接和收发数据。
-
手动创建列表 & channel layers。
-
【全网最详细Django的websocket 通信原理,聊天室,实战案例-哔哩哔哩】http:// https://b23.tv/os2enKj
参考链接http://t.csdn.cn/RyrcC
备用链接django中配置websocket_基于wsgi创建的项目怎么实现websocket_qq_36606793的博客-CSDN博客