• Django实现WebSocket在线聊天室(channels库)


    1.Django实现WebSocket在线聊天室

    1.1 安装channels
    pip install channels==2.3
    
    (saas) F:DesktopPython_StudyCHS-Tracersaas>pip install channels==2.3
    Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
    Collecting channels==2.3
      Downloading 
      ...
    Successfully installed Automat-20.2.0 attrs-20.3.0 autobahn-21.3.1 channels-2.3.0 
    
    1.2 创建Django项目
    1.3 http路由
    url(r"^chat/$", chat_view.chat, name="chat"),  # 聊天室
    
    1.4 http视图函数
    def chat(request):
        return render(request, "chat.html")
    
    1.5 settings添加channels相关配置
    INSTALLED_APPS = [
        'channels',  # 项目中要使用channels做WebSocket了
    ]
    
    ASGI_APPLICATION = "saas.routing.application" # 项目名.routing.application
    
    1.6 创建routing.py(websocket的路由)和comsumers.py(websocket的视图函数)
    image-20210423183534509 image-20210423183624817
    1.7 websocket路由
    # -*- coding:utf-8 -*-
    # 作者:IT小学生蔡坨坨
    # 时间:2021/4/23 18:21
    # 功能:channels相关路由
    
    from channels.routing import ProtocolTypeRouter, URLRouter
    from django.conf.urls import url
    
    from web import consumers
    
    application = ProtocolTypeRouter({
        "websocket": URLRouter([
            url(r'^chat/$', consumers.ChatConsumer),
        ])
    })
    
    1.8 websocket视图函数
    # -*- coding:utf-8 -*-
    # 作者:IT小学生蔡坨坨
    # 时间:2021/4/23 18:25
    # 功能:channels相关视图
    
    from channels.exceptions import StopConsumer
    from channels.generic.websocket import WebsocketConsumer
    
    # 定义一个列表,用于存放当前在线的用户
    CONSUMER_OBJECT_LIST = []
    
    
    class ChatConsumer(WebsocketConsumer):
    
        def websocket_connect(self, message):
            """
            客户端浏览器发来连接请求之后就会被触发
            :param message:
            :return:
            """
    
            # 服务端接收连接,向客户端浏览器发送一个加密字符串
            self.accept()
            # 连接成功
            CONSUMER_OBJECT_LIST.append(self)
    
        def websocket_receive(self, message):
            """
            客户端浏览器向服务端发送消息,此方法自动触发
            :param message:
            :return:
            """
    
            print("接受到消息了。", message)
    
            # 服务端给客户端回一条消息
            # self.send(text_data=message["text"])
            for obj in CONSUMER_OBJECT_LIST:
                obj.send(text_data=message["text"])
    
        def websocket_disconnect(self, message):
            """
            客户端浏览器主动断开连接
            :param message:
            :return:
            """
    
            # 服务端断开连接
            CONSUMER_OBJECT_LIST.remove(self)
            raise StopConsumer()
    
    1.9 前端代码
    <!-- css样式 -->
    <style>
        pre {
            display: block;
            padding: 9.5px;
            margin: 0 0 10px;
            font-size: 18px;
            line-height: 1.42857143;
            color: #333;
            word-break: break-all;
            word-wrap: break-word;
            background-color: #00aaaa;
            border-radius: 12px;
        }
    </style>
    
    <!-- body内容 -->
    <div style=" 600px;height: 574px;margin: auto;margin-top: 20px;">
        <div class="panel panel-success">
            <div class="panel-heading">在线实时聊天室</div>
            <div class="panel-body">
                <div style="border: #f5f5f5 2px solid; 570px;height: 400px;overflow:scroll">
                    <div id="content">
                        <!-- 聊天记录 -->
                    </div>
                </div>
                <div style="border-color: white;margin-top: 10px">
                    <textarea type="text" id="txt" placeholder="请输入消息内容......" class="form-control"></textarea>
                </div>
            </div>
    
            <div class="table">
                <div>
                    <button class="btn btn-danger" onclick="closeLink();" style="margin-left: 74%">断开连接</button>
                    <button class="btn btn-success" onclick="sendMsg();">发送</button>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 消息模板 -->
    <div id="recordTemplate" class="hide">
        <div class="right-info">
            <!-- 用户 -->
            <p>匿名用户:</p>
    
            <!-- 消息内容 -->
            <pre>
    
                </pre>
        </div>
    </div>
    
    
    <!-- js代码 -->
    <script>
        var STATUS; // 是否连接的标志
        var ws = new WebSocket("ws://127.0.0.1:8000/chat/");
    
        ws.onopen = function () {
            // 客户端在握手环节验证成功之后,自动执行此方法
            console.log("连接成功。")
        };
    
        ws.onmessage = function msg(event) {
            var $item = $("#recordTemplate").find('.right-info').clone();
            $item.find('pre').html(event.data);
            $("#content").append($item);
        };
    
        function sendMsg() {
            if (STATUS == false) {
                swal({
                    title: "已断开",
                    text: "当前已断开连接,刷新页面重新连接。"
                });
            } else {
                ws.send($("#txt").val());
                $("#txt").val("");
            }
        }
    
        function closeLink() {
            ws.close();
            STATUS = false;
            console.log("断开连接");
            swal({
                text: "成功断开连接,刷新页面重新连接。"
            });
        }
    </script>
    

    2.效果展示

    image-20210426125043789

    3.总结

    http协议
    	chat路由 --> chat视图函数
    	访问:浏览器发送请求即可
    	
    websocket协议
    	chat路由 --> ChatConsumer(3个方法)
    	访问:new WebSocket对象
    
  • 相关阅读:
    Android框架之高速开发框架xUtil
    树状数组 LA 4329 亚洲赛北京赛区题
    Linq To Sql 增改删
    标题栏显示进度条
    android:inputType参数类型说明
    Illegal resource reference: @*android resources are private and not always present
    android:editable is deprecated: Use an <EditText> to make it editable
    android:contentDescription的作用是什么
    Replace
    图片缓存优化
  • 原文地址:https://www.cnblogs.com/caituotuo/p/14704199.html
Copyright © 2020-2023  润新知