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 ASGI_APPLICATION = '项目名同名的文件名.文件夹下py文件名默认就叫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类会将所有收到的消息加上“运维咖啡吧:”的前缀发送给客户端
from channels.generic.websocket import WebsocketConsumer class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): """客户端请求建立链接时 自动触发""" pass def websocket_receive(self, message): """客户端发送数据过来 自动触发""" pass def websocket_disconnect(self, message): """客户端断开链接之后 自动触发""" pass
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消息 onerror: 如果连接失败,或者发送、接收数据失败,或者数据处理出错都会触发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
转载自:https://www.cnblogs.com/chunyouqudongwuyuan/p/16835639.html