django channels使用和配置及实现群聊
1.1WebSocket原理
http协议
- 连接
- 数据传输
- 断开连接
websocket协议,是建立在http协议之上的。
- 连接,客户端发起。
- 握手(验证),客户端发送一个消息,后端接收到消息再做一些特殊处理并返回。 服务端支持websocket协议。
1.2django框架
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请求,但现在为止只能对某个人进行处理。
2.0 实现群聊
2.1 群聊(一)
前端:
<!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()
2.2 群聊(二)
第二种实现方式是基于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()
好了分享就结束了,其实总的来讲介绍的还是比较浅
如果想要深入一点 推荐两篇博客
【翻译】Django Channels 官方文档 -- Tutorial - 守护窗明守护爱 - 博客园
django channels - 武沛齐 - 博客园
到此这篇关于django channels使用和配置及实现群聊的文章就介绍到这了,更多相关django channels配置内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://blog.csdn.net/weixin_54904917/article/details/124568
相关文章
Django def clean()函数对表单中的数据进行验证操作
这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09- 这篇文章主要介绍了在Django中使用MQTT的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-10
一篇文章带你使用SpringBoot基于WebSocket的在线群聊实现
这篇文章主要介绍了一篇文章带你使用SpringBoot基于WebSocket的在线群聊实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-08解决导入django_filters不成功问题No module named 'django_filter'
这篇文章主要介绍了解决导入django_filters不成功问题No module named 'django_filter',具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-15详解如何使用Docker部署Django+MySQL8开发环境
这篇文章主要介绍了详解如何使用Docker部署Django+MySQL8开发环境,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-19- 这篇文章主要介绍了Django 解决由save方法引发的错误,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-21
- 这篇文章主要介绍了django前端页面下拉选择框默认值设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-10
- 这篇文章主要介绍了django数据模型中null和blank的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-03
- 这篇文章主要介绍了Django表单外键选项初始化的问题及解决方法,需本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,要的朋友可以参考下...2021-04-29
- 本文主要介绍了Django项目连接MongoDB的三种方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-27
- 这篇文章主要给大家介绍了关于使用AJAX和Django获取数据的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-25
- 这篇文章主要介绍了django ajax发送post请求的两种方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2020-04-30
Django开发RESTful API实现增删改查(入门级)
这篇文章主要介绍了Django开发RESTful API实现增删改查(入门级),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-10Django获取model中的字段名和字段的verbose_name方式
这篇文章主要介绍了Django获取model中的字段名和字段的verbose_name方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-20- 这篇文章主要介绍了django中url映射规则和服务端响应顺序的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-10
- 在本篇文章里小编给大家整理的是一篇关于Django后台管理系统的图文使用教学内容,需要的朋友们参考下。...2020-04-22
- 本文总结了如何获得SSL证书并给Django项目配置HTTPS,建议先收藏再阅读,将来有一天你很可能会用到它。...2021-05-01
- 这篇文章主要介绍了Django-ORM-连表正反操作,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-06-13
- 这篇文章主要介绍了django 连接数据库出现1045错误的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-15
- 这篇文章主要介绍了Python Django搭建文件下载服务器的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-10