欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

django中如何实现websocket,通过websocket实现群聊功能

程序员文章站 2022-05-21 14:19:12
...

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()

# 前端四个方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>聊天室</h1>
<input type="text" id="txt">
<button onclick="sendMsg()">发送</button>

<h1>聊天记录</h1>
<div class="record"></div>
<script>
    var ws = new WebSocket('ws://127.0.0.1:8000/chat/');
    // 1 握手环节验证成功后自动触发 onopen
    ws.onopen = function () {
        console.log('握手成功!')
    };
    // 2 给服务端发送消息 send
    function sendMsg() {
        ws.send($('#txt').val())
    }
    // 3 服务端一旦有了消息 自动触发 onmessage
    ws.onmessage = function (args) {
        // 获取发送的数据
        // 创建p标签
        var pEle = $('<p>');
        pEle.text(args.data);
        $('.record').append(pEle)
    };
    // 4 断开链接之后 自动触发 onclose
    ws.onclose = function () {
        ws.close()
    }
</script>
</body>
</html>

django中如何实现websocket,通过websocket实现群聊功能