基于django框架怎样实现websocket请求
Admin 2022-08-17 群英技术资讯 252 次浏览
http协议
websocket协议,是建立在http协议之上的。
django默认不支持websocket,需要安装组件:
pip install channels
配置:
注册channels
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'channels', ]
在settings.py中添加 asgi_application
ASGI_APPLICATION = "ws_demo.asgi.application"
修改asgi.py文件
import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from . import routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ws_demo.settings') # application = get_asgi_application() application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": URLRouter(routing.websocket_urlpatterns), })
在settings.py的同级目录创建 routing.py
from django.urls import re_path from app01 import consumers websocket_urlpatterns = [ re_path(r'ws/(?P<group>\w+)/$', consumers.ChatConsumer.as_asgi()), ]
在app01目录下创建 consumers.py,编写处理处理websocket的业务逻辑。
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): # 有客户端来向后端发送websocket连接的请求时,自动触发。 # 服务端允许和客户端创建连接。 self.accept() def websocket_receive(self, message): # 浏览器基于websocket向后端发送数据,自动触发接收消息。 print(message) self.send("不要回复不要回复") # self.close() def websocket_disconnect(self, message): # 客户端与服务端断开连接时,自动触发。 print("断开连接") raise StopConsumer()
基于django实现websocket请求,但现在为止只能对某个人进行处理。
前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .message { height: 300px; border: 1px solid #dddddd; width: 100%; } </style> </head> <body> <div class="message" id="message"></div> <div> <input type="text" placeholder="请输入" id="txt"> <input type="button" value="发送" onclick="sendMessage()"> <input type="button" value="关闭连接" onclick="closeConn()"> </div> <script> socket = new WebSocket("ws://127.0.0.1:8000/room/123/"); // 创建好连接之后自动触发( 服务端执行self.accept() ) 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); } // 服务端主动断开连接时,这个方法也被触发。 socket.onclose = function (event) { let tag = document.createElement("div"); tag.innerText = "[断开连接]"; document.getElementById("message").appendChild(tag); } function sendMessage() { let tag = document.getElementById("txt"); socket.send(tag.value); } function closeConn() { socket.close(); // 向服务端发送断开连接的请求 } </script> </body> </html>
后端:
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer CONN_LIST = [] class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): print("有人来连接了...") # 有客户端来向后端发送websocket连接的请求时,自动触发。 # 服务端允许和客户端创建连接(握手)。 self.accept() CONN_LIST.append(self) def websocket_receive(self, message): # 浏览器基于websocket向后端发送数据,自动触发接收消息。 text = message['text'] # {'type': 'websocket.receive', 'text': '阿斯蒂芬'} print("接收到消息-->", text) res = "{}SB".format(text) for conn in CONN_LIST: conn.send(res) def websocket_disconnect(self, message): CONN_LIST.remove(self) raise StopConsumer()
第二种实现方式是基于channels中提供channel layers来实现。(如果觉得复杂可以采用第一种)
setting中配置 。
CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer", } }
如果是使用的redis 环境
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() # 将这个客户端的连接对象加入到某个地方(内存 or redis)1314 是群号这里写死了 async_to_sync(self.channel_layer.group_add)('1314', self.channel_name) def websocket_receive(self, message): # 通知组内的所有客户端,执行 xx_oo 方法,在此方法中自己可以去定义任意的功能。 async_to_sync(self.channel_layer.group_send)('1314', {"type": "xx.oo", 'message': message}) #这个方法对应上面的type,意为向1314组中的所有对象发送信息 def xx_oo(self, event): text = event['message']['text'] self.send(text) def websocket_disconnect(self, message): #断开链接要将这个对象从 channel_layer 中移除 async_to_sync(self.channel_layer.group_discard)('1314', self.channel_name) raise StopConsumer()
好了分享就结束了,其实总的来讲介绍的还是比较浅
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
python正则表达式re.search()的基本使用教程是什么?re.search会匹配整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None
topK是常用的一个功能,在python中,numpy等计算库使用了丰富的底层优化,对于矩阵计算的效率远高于python的for-loop实现。因此,我们希望尽量用一些numpy函数的组合实现topK。
这篇文章主要介绍了Python基础之Numpy的基本用法详解,文中有非常详细的代码示例,对正在学习python基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
Python 有 while 语句和 for 语句作为循环处理。虽然 for 语句具有一定数量的进程,但 while 语句是直到满足条件类型的循环进程。本文将详解while无限迭代循环方法,需要的可以了解一下
这篇文章主要介绍了python3中rsa加密算法详情,rsa加密,是一种加密算法,目前而言,加密算法,是对数据、密码等进行加密,下文更多相关介绍,需要的小伙伴可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008