Django使用channel实现websocket
channel
什么是channel?
channel是第三方工具包,对于不支持websocket协议的框架可以借助此包实现websocket
安装
终端安装:
pip3 install channel
pycharm安装:
Project Interprete 搜索 “channel”即可
配置
1、配置 setting.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'channels', ]
配置完app后,还要对ASGI_APPLICATION配置:
# 配置 channel ASGI_APPLICATION = "MiniChat.routing.application"
如果不配置就会报错:
CommandError: You have not set ASGI_APPLICATION, which is needed to run the server.
2.、配置路由
在app下新建routing.py文件,此文件相当于django的url.py
MiniChat/routing.py
from channels.routing import ProtocolTypeRouter, URLRouter from django.conf.urls import url from chat import consumers application = ProtocolTypeRouter({ "websocket":URLRouter([ ]) })
3、创建业务处理文件:consumers.py
此文件相当于django中的view.py文件
MiniChat/consumers.py
#!usr/bin/env python #-*- coding:utf-8 _*- from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): """ 客户端发送请求进来,触发此方法 :param message: :return: """ self.accept() def websocket_receive(self, message): """ 客户端发送消息,触发此方法,并返回数据 :param message: :return: """ self.send() def websocket_disconnect(self, message): """ 客户端主动断开链接,触发此方法 :param message: :return: """ # 服务端触发异常 StopConsumer raise StopConsumer
consumers.py
最终项目目录:
案例:WebChat
基于上面的配置,先创建一个视图:
from django.shortcuts import render # Create your views here. def index(request): return render(request, "index.html")
然后在app01中创建一个templates包,在这个包中创建一个index.html.再去实现html文件:
Django默认模板查找顺序是从根目录查找,找不到再去app中查找
<div> <div> <input type="text" id="txt"> <input type="button" value="send" onclick="sendMsg();"> <input type="button" value="close" onclick="closeConn();"> </div> <h2>聊天记录</h2> <div id="content"> </div> </div>
现在跑一下项目文件,浏览器页面显示:
现在再去完善下html文件
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script> <script> var ws = new WebSocket("ws://127.0.0.1:8000/chat/"); ws.onopen = function(){ // 客户端验证握手环节完成之后,自动执行该方法 console.log("链接成功。。。") }; ws.onmessage = function (event) { // 接受服务端发送的消息 // 客户端完成握手验证之后 触发该方法 console.log(event.data); var tag = $("<div>"); tag.text(event.data); $("#content").append(tag); console.log(1) }; function sendMsg() { // ws.send():发送消息 ws.send($("#txt").val()); }; function closeConn() { // ws.close():关闭Websocket链接 console.log("断开链接。。。"); ws.close(); }; </script>
在这里就使用简单的方式实现多人聊天的功能,对consumers.py做以下修改:
USER_list = [] class ChatConsumer(WebsocketConsumer): def websocket_connect(self, message): """ 客户端发送请求进来,触发此方法 :param message: :return: """ self.accept() # 执行accept之后代表链接成功 USER_list.append(self) # 将每一个链接的用户添加到列表中 def websocket_receive(self, message): """ 客户端发送消息,触发此方法,并返回数据 :param message: :return: """ # print("msg:", message) # msg: {'type': 'websocket.receive', 'text': '123'} data = message["text"] # 获取字典中的数据 # self.send("over") for user in USER_list: # 遍历用户列表返回消息 user.send(data) def websocket_disconnect(self, message): """ 客户端主动断开链接,触发此方法 :param message: :return: """ # 服务端触发异常 StopConsumer USER_list.remove(self) # 将每一个链接的用户从列表中删除 raise StopConsumer
至此,就简单实现了多人在线聊天的功能。