django中websocket的具体使用

yizhihongxing

下面我将为你详细讲解 Django 中 WebSocket 的具体使用,并提供两个示例说明。

什么是 WebSocket

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它使得浏览器和服务器之间可以在任何时候异步地进行数据传输,这使得实时 Web 应用程序成为可能。

在 WebSocket 协议之前,要实现实时通信,必须使用轮询或长轮询技术。轮询是一种客户端不断地向服务器发起请求,以便查看是否有新的数据可用的技术。长轮询则是一种从服务器端推送数据到客户端,但保持连接处于打开状态的技术。

WebSocket 协议的主要特点如下:

  • 零延迟通信
  • 双向通信
  • 实时性高
  • 性能好
  • 跨平台

Django 中实现 WebSocket

Django 中可以使用 django-websocket-redis 库来实现 WebSocket。 django-websocket-redis 是一个基于 Redis 的 Django WebSocket 实现。

安装 django-websocket-redis

首先在你的 Django 项目中安装 django-websocket-redis 依赖:

pip install channels django-redis

配置 redis

  1. 根据你使用的 redis 服务端,完成对 redis 的安装和启动,这里不再细讲。
  2. 在 Django 中的 settings.py 中进行相关配置,配置内容如下:
CHANNEL_LAYERS = {
    "default": {
        # 使用 channels_redis 作为通道层
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        # 配置 Redis 地址
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

创建 WebSocket consumer

新建一个 Python 文件,命名为 consumers.py,并完成代码编写:

from channels.generic.websocket import AsyncWebsocketConsumer
# 异步获取 WebSocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        print("websocket connected...")
        await self.accept()

    async def disconnect(self, close_code):
        print("websocket disconnected...")

    async def receive(self, text_data):
        await self.send(text_data=json.dumps({
            "message": text_data
        }))
  • AsyncWebsocketConsumer是Django-Channels中实现 Websocket 的异步类,需要引入。
  • connect() 方法中,WebSocket 连接被建立,初始化函数
  • disconnect() 方法中,WebSocket 连接被断开,清理函数
  • receive() 方法中,WebSocket 接收到数据时调用,激活函数

URL 配置

在你的 Django 项目中创建一个 routing.py 文件,完成代码编写:

from django.urls import re_path

from .consumers import ChatConsumer

websocket_urlpatterns = [
    re_path(r'ws/chat/$', ChatConsumer.as_asgi()),
]

在你的 Django 项目中的 settings.py 文件中加入:

ASGI_APPLICATION = 'your_project_name.routing.application'
# 该路径根据自己的路径修改,也可在同级目录创建一个 routing.py 文件

运行 WebSocket

在 Django 项目目录下运行如下命令以运行 WebSocket:

daphne -b 0.0.0.0 -p 8000 your_project_name.routing:application

WebSocket 示例

Chat 程序

Chat 程序是从所有连接的客户端接收消息并将其广播给所有其他客户端的简单聊天应用程序。 在本例中,您将学习如何通过仅使用纯 Django 框架和 Django channels 库来实现 chatroom 的 WebSocket 的高级流程。

步骤:

  1. 在 Django 项目中创建 routing.py 文件,完成代码编写
from django.urls import re_path

from . import consumers  # 导入消费方法

websocket_urlpatterns = [
    re_path(r'ws/chat/$', consumers.ChatConsumer.as_asgi()),
    # as_asgi()是将 WebSocketConsumer 转化为 ASGI 应用程序
]
  1. 在 Django 项目中创建 consumers.py 文件,完成代码编写。
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer

class ChatConsumer(WebsocketConsumer):
    def connect(self):
        print("websocket connected ...")
        # 将新连接添加到组中
        async_to_sync(self.channel_layer.group_add)(
            "chat",
            self.channel_name
        )
        self.accept()

    def disconnect(self, close_code):
        # 从组中删除连接
        async_to_sync(self.channel_layer.group_discard)(
            "chat",
            self.channel_name
        )
        print("websocket disconnected ...")

    # 接收消息并将其转发到组中的所有连接
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        async_to_sync(self.channel_layer.group_send)(
            "chat",
            {
                "type": "chat_message",
                "message": message
            }
        )

    # 接收来自组的消息并将其发送到连接 Socket 的客户端
    def chat_message(self, event):
        message = event['message']

        self.send(text_data=json.dumps({
            "message": message
        }))
  1. routing.py 集成到 Django 的路由中。
from django.urls import path, include

urlpatterns = [
    path('', include('your_app.urls')),
]
  1. 使用 jQuery 向 WebSocket 发送请求。
<script>
    const chatSocket = new WebSocket(
        'ws://' + window.location.host +
        '/ws/chat/'
    );

    chatSocket.onmessage = function(e) {
        const data = JSON.parse(e.data);
        const message = data.message;
        console.log(message);
    };

    chatSocket.onclose = function(e) {
        console.log('Chat socket closed unexpectedly');
    };

    document.querySelector('#chat-message-input').focus();
    document.querySelector('#chat-message-input').onkeyup = function(e) {
        if (e.keyCode === 13) {  // enter 键
            document.querySelector('#chat-message-submit').click();
        }
    };

    document.querySelector('#chat-message-submit').onclick = function(e) {
        const messageInputDom = document.querySelector('#chat-message-input');
        const message = messageInputDom.value;
        chatSocket.send(JSON.stringify({
            'message': message
        }));
        messageInputDom.value = '';
    };

</script>

游戏程序

游戏程序是一种通过 WebSocket 在游戏服务器和客户端之间进行数据传输的高级应用程序,本例中将学习如何使用 Django channels 库实现。

步骤:

  1. 在 Django 项目中创建 routing.py 文件,完成代码编写:
from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/game/(?P<room_name>\w+)/$', consumers.GameConsumer.as_asgi()),
]
  1. 在 Django 项目中创建 consumers.py 文件,完成代码编写。
import json
import random
from channels.generic.websocket import WebsocketConsumer

class GameConsumer(WebsocketConsumer):
    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'game_%s' % self.room_name

        # 将新的连接添加到 room_group 分组中
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'game_start',
                'message': '游戏开始',
                'gameStatus': 1,  # 1 表示游戏中,0 表示游戏结束
                'position': random.randint(1, 6)  # 生成 1~6 的随机数
            }
        )

    def disconnect(self, close_code):
        # 将连接从 room_group 分组中删除
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    # 接收来自 WebSocket 的消息,转发到 room_group 分组中
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'game_process',
                'message': message,
                'position': random.randint(1, 6)  # 生成 1~6 的随机数
            }
        )

    # room_group 分组中的信息处理
    def game_start(self, event):
        message = event['message']
        gameStatus = event['gameStatus']
        position = event['position']

        # 发送消息给 WebSocket
        self.send(text_data=json.dumps({
            'message': message,
            'gameStatus': gameStatus,
            'position': position
        }))

    def game_process(self, event):
        message = event['message']
        position = event['position']

        # 发送消息给 WebSocket
        self.send(text_data=json.dumps({
            'message': message,
            'position': position
        }))
  1. routing.py 集成到 Django 的路由中。
from django.urls import path, include

urlpatterns = [
    path('', include('your_app.urls')),
]
  1. 使用 jQuery 的 Ajax 方法创建 WebSocket 连接。
<script>
    const roomName = 'your_room_name';
    const wsStartGame = new WebSocket(
        'ws://' +
        window.location.host +
        '/ws/game/' +
        roomName +
        '/'
    );

    wsStartGame.onmessage = function(e) {
        const data = JSON.parse(e.data);
        const message = data.message;
        const gameStatus = data.gameStatus;
        const position = data.position;

        console.log(message);
        console.log(gameStatus);
        console.log(position);

        if (gameStatus === 0) {  // 游戏结束
            // End
        }
    };

    wsStartGame.onclose = function(e) {
        console.log('Websocket Closed');
    };

    $(function() {
        $.ajax({
            url: '{% url "game_start" %}',
            dataType: 'json',
            success: function(response) {
                console.log(response);

                wsStartGame.send(JSON.stringify({
                    'message': response.message,
                    'gameStatus': response.gameStatus,
                    'position': response.position
                }));
            },
            error: function(response) {
                console.log(response);
            }
        });

        $('#button_start').on('click', function() {
            $.ajax({
                url: '{% url "game_process" %}',
                dataType: 'json',
                data: {'message': 'game start'},
                success: function(response) {
                    console.log(response);

                    wsStartGame.send(JSON.stringify({
                        'message': response.message,
                        'position': response.position
                    }));
                },
                error: function(response) {
                    console.log(response);
                }
            });
        });
    });
</script>

以上就是 Django 中 WebSocket 的基本实现方法及其两个示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django中websocket的具体使用 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • Python – Django – 使用 Pycharm 连接 MySQL 数据库

    在 Pycharm 的右上方找到 Database 点击 依次点击,选择 MySQL 数据库 点击 Download 下载驱动文件 下载完成后对数据库的相关信息进行填写 填写完成后点击“Test Connection”,如果出现 Successful 就说明连接成功 然后点击“应用”,再点击“确定” 左边这个窗口是写 SQL 语句的地方  例如查询 app0…

    Django 2023年4月10日
    00
  • Django路由系统详解

    Django是一款流行的Web开发框架,其强大的路由系统是其架构的核心之一。Django路由系统使用正则表达式来匹配URL,并将其映射到适当的视图函数。 以下是关于Django路由系统的详细讲解。 Django路由系统的特点 易于使用:Django路由系统使用简单的正则表达式来定义URL模式,这使得开发人员很容易理解和管理路由系统。 灵活性:Django路由…

    Django 2023年3月11日
    00
  • 【Django drf】视图类APIView之五层封装 ApiView的类属性 drf配置文件

    目录 ApiView的类属性 drf 配置文件之查找顺序 drf之请求 APIView之请求相关配置 drf之响应 APIView之响应相关配置 Response对象属性 视图类 序列化类 路由 基于GenericAPIview 写五个接口 GenericAPIview必备设置 查询所有 get_queryset() get_serializer() get…

    Django 2023年4月13日
    00
  • 使用Nginx+uWSGI+Django方法部署Django程序

      第一步先解决uwsgi与django的桥接。解决在没有nginx的情况下,如何使用uwsgi+DJANGO来实现一个简单的WEB服务器。 第二步解决uwsgi与Nginx的桥接。通过nginx与uwsgi的桥接,打通nginx与django的连通,从而比较完美的实现django的部署。 本文将分成五步来详细阐述uwsgi+django的部署方式。ngin…

    Django 2023年4月12日
    00
  • Django 连接Mysql异常处理

    启动manage.py提示 连接数据库异常 django.db.utils.OperationalError: (2003, “Can’t connect to MySQL server on ‘127.0.0.1’ ([Errno 10061] )”)   此时cmd.exe  输入mysql指令同样有异常提示: C:\Windows\system32&g…

    Django 2023年4月11日
    00
  • django的登录注册系统的示例代码

    首先,需要先说明一下Django的登录注册系统是如何实现的。 Django使用的是MVC(Model-View-Controller)框架,其中登录注册系统主要是使用Django的auth模块实现的。 接下来,我将为你详细讲解Django的登录注册系统的示例代码的完整攻略。 示例1:Django用户注册系统的示例代码 步骤1:创建新的Django项目 可以使…

    Django 2023年5月15日
    00
  • Django学习笔记:django orm extra

    extra 在django orm中使用复杂的sql语句extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 有些情况下,Django 的查询语法难以简练地表达复杂的 WHERE 子句。对于这种情况,Django 提供了 extr…

    Django 2023年4月9日
    00
  • Django模型中的admin后台管理无法显示字段

    在执行django后台管理时,登陆到http://127.0.0.1:8000/admin/,进入页面后没有对应的字段显示。请解决?   代码: models.py from django.db import models # Create your models here. #发布会表 from django.db import models class …

    2023年4月9日
    00
合作推广
合作推广
分享本页
返回顶部