这篇文章主要介绍“django channels使用、配置及实现群聊的方法”,在日常操作中,相信很多人在django channels使用、配置及实现群聊的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”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 osfrom django.core.asgi import get_asgi_applicationfrom 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 WebsocketConsumerfrom 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 WebsocketConsumerfrom 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 WebsocketConsumerfrom channels.exceptions import StopConsumerfrom 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使用、配置及实现群聊的方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!