zoukankan      html  css  js  c++  java
  • 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()
    
    
    # 前端四个方法
    <!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>
    

  • 相关阅读:
    .net core 注入的几种方式
    Entity framework Core 数据库迁移
    Net Core中使用Newtonsoft.Json进行序列化保持原有大小写
    .net core 中间件
    .net core webapi 中使用Swagger
    HttpClient使用
    使用第三方库(Senparc)完成小程序支付
    JDK官网下载与安装过程
    制作多系统U盘
    WIN7共享打印机
  • 原文地址:https://www.cnblogs.com/godlover/p/12701157.html
Copyright © 2011-2022 走看看