• Django中使用websocket并实现简易聊天室


    django使用websocket并实现简易聊天室

    django默认只支持http协议

    如果你想让django即支持http协议又支持websocket协议,则需要做以下配置

    前期配置

    前提需要安装channels:

    channles的安装:

    """
    注意事项
    	1.不要安装最新版本的channles,建议安装2.3版本即可
    	2.python解释器建议使用3.6
    """
    pip3 install channels==2.3
    

    1.配置文件中注册channels应用

    INSTALLED_APPS = [
        # 1 注册channles应用
        'channels'
    ]
    

    2.settings.py配置文件配置参数

    # 2 配置启动需要的参数
    ASGI_APPLICATION = 'myapi.routing.application'
    # ASGI_APPLICATION = '项目名同名的文件夹名.内部的py文件名(默认就叫routing).routing文件内的变量名(默认就叫application)'
    

    3.固定配置

    # 在项目名同名的文件夹下创建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)
        ])
    })
    

    总结:配置完成后django由原来默认的wsgiref替换成asgi启动(asgi内部是基于达芙妮)

    上述配置完成后 ,django就会同时支持http协议和websocket协议

    """
    原先基于http协议的路由与视图函数对应关系还是跟之前一样urls.py、views.py
    
    针对websocket协议的路由与视图函数对应关系则需要在routing.py和consumers.py(在对应的应用下创建即可)
    """
    

    业务逻辑代码

    # consumers.py
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer
    
    
    
    class ChatConsumer(WebsocketConsumer):
        def websocket_connect(self, message):
            """
            客户端请求链接之后自动触发
            :param message: 消息数据
            """
            pass
        
        def websocket_receive(self, message):
            """
            客户端浏览器发送消息来的时候自动触发
            :param message: 消息数据
            """
            pass
        
        def websocket_disconnect(self, message):
            """
            客户端断开链接之后自动触发
            :param message:  
            """
            pass
    

    基于channels完成聊天室

    """
    http协议
    	index	>>> index函数
    	访问:浏览器发送请求即可
    
    websocket协议
    	chat >>> ChatConsumer类(3个方法)
    	访问:借助于new WebSocket对象
    """
    
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer
    
    
    consumer_object_list = []
    
    
    class ChatConsumer(WebsocketConsumer):
        def websocket_connect(self, message):
            """
            客户端请求链接之后自动触发
            :param message: 消息数据
            """
            # print('请求链接')
            self.accept()  # 建立链接
    
            # 链接成功之后就将当前链接对象往列表中存一份
            consumer_object_list.append(self)
    
    
        def websocket_receive(self, message):
            """
            客户端浏览器发送消息来的时候自动触发
            :param message: 消息数据  {'type': 'websocket.receive', 'text': '你好啊 美女'}
            """
            # 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):
            """
            客户端断开链接之后自动触发
            :param message:
            """
            # 客户端断开链接之后 应该将当前客户端对象从列表中移除
            consumer_object_list.remove(self)
            raise StopConsumer()  # 主动报异常 无需做处理 内部自动捕获
    
    <h1>聊天室</h1>
    <div>
        <input type="text" id="text" placeholder="请输入">
        <input type="button" value="发送" onclick="sendMsg()">
        <input type="button" value="断开链接" onclick="close()">
    </div>
    
    <h1>聊天纪录</h1>
    <div id="content">
    
    </div>
    
    <script>
        var ws = new WebSocket('ws://127.0.0.1:8000/chat/');
        // 1 发送消息 ws.send()
        // 2 握手成功之后 自动触发  ws.onopen
        // 3 服务端发送消息过来 自动触发  ws.onmessage
        // 4 断开链接 ws.close()
    
        // 0 握手成功之后自动触发
        ws.onopen = function () {
            alert('建立成功')
        };
    
        // 1 给服务端发送消息
        function sendMsg() {
            ws.send($('#text').val());
        }
    
        // 2 接受服务端发送过来的消息
        ws.onmessage = function (event) {  // event是对象
            var dataValue = event.data;  // 获取服务端的数据
            // 用DOM操作将数据动态渲染到页面上
            var pEle = $('<p>');
            pEle.text(dataValue);
            $('#content').append(pEle)
        };
    
        // 3 断开链接
        function close() {
            ws.close()
        }
    </script>
    

    总结

    """
    后端三个方法
    	websocket_connect
    	websocket_receive
    	websocket_disconnect
    
    前端四个方法
    	// 1 发送消息 ws.send()
      // 2 握手成功之后 自动触发  ws.onopen
      // 3 服务端发送消息过来 自动触发  ws.onmessage
      // 4 断开链接 ws.close()
    """
    

    注意我们上面的代码实现的群聊功能并不是真正的合理,后续如果想要真正实现群聊功能,官方提供了一个方法channel-layers模块,

  • 相关阅读:
    持续集成 自动化构建、测试、部署您的Coding代码
    MySQL主从 常见的错误及解决方案
    老王带你走过 Kafka 入门教程
    Spring Cloud Eureka 常用配置及说明
    关于智慧大数据中心平台建设思路
    工作经验是积累总结出来的
    程序员晋级CTO之路的8大准则
    Spring Cloud Feign 使用方法与性能优化
    Elasticsearch(ES)API 增删查改常用操作
    ELK 日志采集 实战教程
  • 原文地址:https://www.cnblogs.com/guapitomjoy/p/12381293.html
Copyright © 2020-2023  润新知