django中如何实现websocket,真正通过websocket实现群聊功能
django中如何实现websocket
安装
pip3 install channles==2.3
1 解释器版本建议使用python3.6
2 channles模块版本建议使用2.3
基本配置
配置文件中注册app
配置文件中定义配置
对应应用下新建py文件并且在文件内部定义变量
完成上述配置以后,django就会既支持http又支持websocket
django,pycharm创建的django项目会自动帮你创建全局的templates文件夹,
也可以在每一个应用下创建templates模板文件夹
如果出现多个应用和全局都有模板文件夹的情况,会优先查找全局,如果全局没有,会按照配置文件中注册的app的顺序从上往下依次进行查找每一个应用下的templates
每一个应用都可以有自己的urls.py,views.py和templates,static
配置完成以后同时支持http与websocket的原因(源码解析)
class ProtocolTypeRouter:
"""
Takes a mapping of protocol type names to other Application instances,
and dispatches to the right one based on protocol name (or raises an error)
"""
def __init__(self, application_mapping):
self.application_mapping = application_mapping
if "http" not in self.application_mapping:
self.application_mapping["http"] = AsgiHandler
配置完成以后
routing.py
from channels.routing import ProtocolTypeRouter,URLRouter
from django.conf.urls import url
from app01 import consumers
application = ProtocolTypeRouter({
'websocket':URLRouter([
# websocket相关的路由
url(r'^chat/',consumers.ChatConsumer)
])
})
consumers.py
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
"""
http协议
index路径 index视图函数
访问:浏览器窗口直接输入的地址的
websocket协议
chat路径 ChatConsumer视图类
访问:new WebSocket对象访问
"""
真正通过websocket实现群聊功能:
通过自己维护一个列表存储链接对象的方式完成了简易版本的群聊,其实还可以用channels提供的模块,channel-layers
# 后端 三个方法
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
consumer_object_list = []
class ChatConsumer(WebsocketConsumer):
def websocket_connect(self, message):
# 客户端请求链接时 自动触发
print('请求链接')
self.accept()
# 建立链接 并且自动帮你维护每一个客户端
# 将链接在列表中存储一份
consumer_object_list.append(self)
def websocket_receive(self, message):
# 客户端发送数据过来 自动触发
print(message)
text = message.get('text')
# # 给客户端发送消息 单独发送
# self.send(text_data=text)
# 给所有的链接对象发送数据
for obj in consumer_object_list:
obj.send(text_data=text)
def websocket_disconnect(self, message):
# 客户端断开链接之后 自动触发
print('断开链接')
# 客户端断开之后,应该将当前对象移除
consumer_object_list.remove(self)
raise StopConsumer()
# 前端四个方法
Title
聊天室
聊天记录