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
至此,就简单实现了多人在线聊天的功能。