django实现websocket
简述
简述:django实现websocket,之前django-websocket退出到3.0之后,被废弃。官方推荐大家使用channels。
channels通过升级http协议 升级到websocket协议。保证实时通讯。也就是说,我们完全可以用channels实现我们的即时通讯。而不是使用长轮询和计时器方式来保证伪实时通讯。
他通过改造django框架,使django既支持http协议又支持websocket协议。
官方文档地址:https://channels.readthedocs.io/en/stable/
创建项目名为webapp 的django项目,目录结构如下
project
- webapp
- __init__.py
- settings.py
- urls.py
- wsgi.py
- manage.py
按照第三方库
python本身只支持http协议 使用websocket需要下载第三方库
pip install -U channels
'''
默认下载最新版,django版本也会变为3.2
如果不想变更django版本执行pip install -U channels==2.3
'''
在django2.2以上版本会内置支持ASGI
安装在windows机器的时候。需要自信的C++支持,报错的时候,报错有地址告诉你下载URL
配置
需要在seting.py里配置,将我们的channels加入INSTALLED_APP里。
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
...
'channels',
)
ASGI_APPLICATION = 'webapp.routing.application'
'''
ASGI_APPLICATION 指定主路由的位置为webapp下的routing.py文件中的application
'''
创建routing.py路由文件
setting.py的同级目录下创建routing.py路由文件,routing.py类似于Django中的url.py指明websocket协议的路由
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter({
# 暂时为空,下文填充
})
启动项目
'''
wsgi,只支持http请求
asgi,wsgi+异步+websockt
'''
出现上图及配置完成
使用
假设你已经创建好了一个叫chat的app,并添加到了settings.py的INSTALLED_APPS中,app的目录结构大概如下
chat
- migrations
- __init__.py
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
url:
from django.urls import path
from chat.views import chat
urlpatterns = [
path('chat', chat, name='chat-url')
]
views:
from django.shortcuts import render
def chat(request):
return render(request, 'chat/index.html')
接下来我们利用Channels的WebSocket协议实现消息的发送接收功能
首先需要建立一个django项目。其中在你自己的app下面 生成consumers.py和routing.py配置文件。
consumers.py:相当于django的视图,也就是说所有的websocket路由过来的执行的函数都在consumers.py类似于django的视图views.py
routing.py:是websocket中的url和执行函数的对应关系。相当于django的urls.py,根据映射关系,当websocket的请求进来的时候,根据用户的请求来触发我们的consumers.py里的方法。
1. 先从路由入手,上边我们已经创建了routing.py路由文件,现在来填充里边的内容
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
ProtocolTypeRouter: ASIG支持多种不同的协议,在这里可以指定特定协议的路由信息,我们只使用了websocket协议,这里只配置websocket即可
AuthMiddlewareStack: django的channels封装了django的auth模块,使用这个配置我们就可以在consumer中通过下边的代码获取到用户的信息
def connect(self):
self.user = self.scope["user"]
self.scope类似于django中的request,包含了请求的type、path、header、cookie、session、user等等有用的信息
URLRouter: 指定路由文件的路径,也可以直接将路由信息写在这里,代码中配置了路由文件的路径,会去chat下的routeing.py文件中查找
websocket_urlpatterns,chat/routing.py内容如下
from django.urls import path
from chat.consumers import ChatConsumer
websocket_urlpatterns = [
path('ws/chat/', ChatConsumer),
]
routing.py路由文件跟django的url.py功能类似,语法也一样,意思就是访问ws/chat/都交给ChatConsumer处理
2.接着编写consumer,consumer类似django中的view,内容如下
from channels.generic.websocket import WebsocketConsumer
import json
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = '运维咖啡吧:' + text_data_json['message']
self.send(text_data=json.dumps({
'message': message
}))
这里是个最简单的同步websocket consumer类,connect方法在连接建立时触发,disconnect在连接关闭时触发,receive方法会在收到消息后触发。整个ChatConsumer类会将所有收到的消息加上“运维咖啡吧:”的前缀发送给客户端
3.最后再Vue中添加websocket支持
<script>
export default {
name : 'test',
data() {
return {
websock: null,
}
},
created() {
this.initWebSocket();
},
destroyed() {
this.websock.close() //离开路由之后断开websocket连接
},
methods: {
initWebSocket(){ //初始化weosocket
const wsuri = "ws://127.0.0.1:8080";
this.websock = new WebSocket(wsuri);
this.websock.onmessage = this.websocketonmessage;
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onclose = this.websocketclose;
},
websocketonopen(){ //连接建立之后执行send方法发送数据
let actions = {"test":"12345"};
this.websocketsend(JSON.stringify(actions));
},
websocketonerror(){//连接建立失败重连
this.initWebSocket();
},
websocketonmessage(e){ //数据接收
const redata = JSON.parse(e.data);
},
websocketsend(Data){//数据发送
this.websock.send(Data);
},
websocketclose(e){ //关闭
console.log('断开连接',e);
},
},
}
</script>
'''
onopen: 当浏览器和websocket服务端连接成功后会触发onopen消息
one rror: 如果连接失败,或者发送、接收数据失败,或者数据处理出错都会触发onerror消息
onmessage: 当浏览器接收到websocket服务器发送过来的数据时,就会触发onmessage消息,参数e包含了服务端发送过来的数据
onclose: 当浏览器接收到websocket服务器发送过来的关闭连接请求时,会触发onclose消息
'''
最终chat结构
chat
- migrations
- __init__.py
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
- rouging.py
- consumer.py
标签:websocket,实现,py,django,channels,routing,chat
From: https://www.cnblogs.com/chunyouqudongwuyuan/p/16835639.html