django中websocket的具体使用

下面我将为你详细讲解 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日

相关文章

  • django os.environ慎用setdefault操作环境变量

    在绝大多数情况下,如果需要在程序运行过程中设置环境变量,使用os.environ.setdefault函数是没有任何问题的,但是有两种场景下setdefault会造成意外的问题,需要慎用: 如果程序执行前,系统里已经存在了某环境变量(如ENV=VAL1),此时如果在程序中用setdefault函数对该环境变量设置另一个不同的值(如VAL2),会因为setde…

    Django 2023年4月13日
    00
  • Django入门使用示例

    以下是“Django入门使用示例”的完整攻略。 Django入门使用示例 本文将介绍Django的入门使用示例,包括如何创建Django项目和应用,如何定义模型,并进行数据迁移和数据查询等操作。本文的示例采用Django 3.2 版本。 创建Django项目和应用 首先,我们需要创建Django项目。在命令行中输入以下命令: django-admin sta…

    Django 2023年5月16日
    00
  • (4)django的新手三件套(返回页面、返回字符、重定向)

    from django.shortcuts import render,HttpResponse,redirect 新手三件套,前期开发都会用到 render   #向浏览器返回页面 HttpResponse   #向浏览器返回字符内容 redirect   #重定向   django里有分层的概念 urls.py就是路由层 views.py 就是视图层 t…

    Django 2023年4月12日
    00
  • Django MySQL 数据库连接

    Django 1.11 官方文档 常规说明 数据库连接 CONN_MAX_AGE 定义数据库连接时限(ALL) default:0 保存在每个请求结束时关闭数据库连接的历史行为。None:保持长连接Other:xx 单位秒 连接管理 Django连接发生在每次请求时,如果没有可用连接便主动建立连接,如果限制了连接时间的话。 警告 每个线程包含自己的数据库连接…

    Django 2023年4月13日
    00
  • Django和Mezzanine初探

    Python框架中,Django是最著名的一个,Mezzanine是基于Django的一个框架。最初在决定学习Django的之后,先看了Django book一段时间,然后就开始四处寻找有价值的App,对我这个懒人来说,有App用,总比自己写要好。  后来看到了一个Mezzanine的介绍,将它比为Wordpress,wordpress是PHP的,而Mezz…

    Django 2023年4月11日
    00
  • 如何设置django 连接 db.sqlite3

             

    Django 2023年4月13日
    00
  • 3. 投票 案例项目(合集)

    3.投票-1创建项目和子应用 创建项目 命令 $ python django-admin startproject mysite 目录结构 mysite/ # 项目容器、可任意命名 manage.py # 命令行工具 mysite/ # 纯 Python 包 # 你引用任何东西都要用到它 __init__.py # 空文件 告诉Python这个目录是Pyth…

    2023年4月10日
    00
  • Pycharm创建Django项目示例实践

    下面为您详细讲解“Pycharm创建Django项目示例实践”的完整攻略。 Pycharm创建Django项目示例实践 环境准备 安装Python环境:首先需要安装最新版Python环境,可以去Python官网下载安装,安装完成后可以在命令行中输入python -V查看Python的版本,如果成功安装,会显示Python的版本号。 安装Pycharm:Pyc…

    Django 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部