前端Python应用指南(八)WebSocket与实时应用:用Flask和Django实现聊天系统

《写给前端的python应用指南》系列:

  • (一)快速构建 Web 服务器 - Flask vs Node.js 对比
  • (二)深入Flask:理解Flask的应用结构与模块化设计
  • (三)Django vs Flask:哪种框架适合构建你的下一个Web应用?
  • (四)Django实战:创建一个简单的博客系统
  • (五)用FastAPI快速构建高性能API
  • (六)构建RESTful API:使用Flask和Django实现用户认证与授权
  • (七)使用SQLAlchemy与Django ORM

在现代应用中,实时通信已成为非常重要的一部分,尤其是社交应用、在线客服系统、多人游戏、协作工具等场景。实现实时通信的常用技术之一就是WebSocket,它允许客户端和服务器之间建立一个持久的双向连接,在这个连接上,数据可以随时双向传输,从而实现实时数据更新。

在本篇博文中,我们将通过使用Python中的FlaskDjango框架来实现一个简单的聊天系统,演示如何使用WebSocket技术进行实时通信。

一、WebSocket概述

WebSocket是一种在单个TCP连接上进行全双工通信的协议,它特别适用于需要实时通信的应用,如在线聊天、实时推送、股票行情、多人在线游戏等。

与传统的HTTP协议不同,WebSocket连接一旦建立,客户端和服务器之间可以持续通信,而不需要每次都重新建立连接。客户端发出请求后,服务器可以主动推送数据给客户端,而无需等待客户端发起请求。

二、Flask实现WebSocket实时聊天

Flask本身并不内置对WebSocket的支持,但我们可以借助Flask-SocketIO扩展来实现WebSocket功能。Flask-SocketIO提供了一个简单的接口,使得Flask应用能够支持WebSocket协议。

2.1 安装依赖

首先,我们需要安装Flask-SocketIO和Eventlet(一个用于支持异步操作的库)。

pip install flask flask-socketio eventlet
2.2 创建Flask应用

我们将创建一个简单的Flask聊天应用,客户端可以通过WebSocket与服务器进行实时通信。

  1. 创建Flask应用与SocketIO配置:
from flask import Flask, render_template
from flask_socketio import SocketIO, send

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='eventlet')

@app.route('/')
def index():
    return render_template('index.html')

# 监听消息事件
@socketio.on('message')
def handle_message(msg):
    print('Received message: ' + msg)
    send(msg, broadcast=True)  # 将收到的消息广播给所有连接的客户端

if __name__ == '__main__':
    socketio.run(app)
  1. 创建聊天前端页面:

templates文件夹下创建index.html,这是我们的聊天前端界面,使用SocketIO与后端进行连接。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask WebSocket Chat</title>
    <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
</head>
<body>
    <h1>Flask WebSocket Chat</h1>
    <div id="messages"></div>
    <input id="message" type="text" placeholder="Type a message...">
    <button onclick="sendMessage()">Send</button>

    <script>
        const socket = io.connect('http://' + document.domain + ':' + location.port);

        // 当接收到消息时,更新聊天窗口
        socket.on('message', function(msg) {
            const messageDiv = document.createElement('div');
            messageDiv.textContent = msg;
            document.getElementById('messages').appendChild(messageDiv);
        });

        // 发送消息
        function sendMessage() {
            const message = document.getElementById('message').value;
            socket.send(message);
            document.getElementById('message').value = '';
        }
    </script>
</body>
</html>
2.3 运行Flask应用

运行Flask应用后,可以通过浏览器访问http://127.0.0.1:5000来启动聊天系统。多个浏览器或标签页同时访问时,输入的消息将会实时出现在所有页面上。

python app.py

三、Django实现WebSocket实时聊天

在Django中实现WebSocket支持,推荐使用Django Channels,这是Django官方推荐的一个用于处理WebSocket和其他异步协议的扩展。

3.1 安装依赖

首先,我们需要安装Django ChannelsChannels Redis(用于消息的分发和广播)。Channels基于Django的异步支持,允许我们处理WebSocket连接。

pip install django channels channels_redis
3.2 创建Django项目
  1. 创建Django项目与应用:
django-admin startproject mychat
cd mychat
python manage.py startapp chat
  1. 配置settings.py

mychat/settings.py中添加channelschat应用,并配置ASGI接口。

INSTALLED_APPS = [
    ...
    'channels',
    'chat',
]

# 配置ASGI接口
ASGI_APPLICATION = 'mychat.asgi.application'
  1. 创建asgi.py

在项目根目录下创建asgi.py文件,用于配置ASGI应用。

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from chat import consumers

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mychat.settings')

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    'websocket': AuthMiddlewareStack(
        URLRouter([
            path('ws/chat/', consumers.ChatConsumer.as_asgi()),
        ])
    ),
})
  1. 创建ChatConsumer

chat/consumers.py中创建ChatConsumer类,用于处理WebSocket连接。

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_group_name = 'chat_room'

        # 加入房间组
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        # 接受WebSocket连接
        await self.accept()

    async def disconnect(self, close_code):
        # 离开房间组
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # 接收来自WebSocket的消息
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # 广播消息到房间组
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    # 从房间组发送消息
    async def chat_message(self, event):
        message = event['message']

        # 发送消息到WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))
  1. 配置routing.py

chat应用中创建routing.py,将WebSocket的URL路由指向ChatConsumer

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/chat/', consumers.ChatConsumer.as_asgi()),
]
  1. 配置Channel Layer:

settings.py中配置Redis作为Channel Layer的后端。

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}
  1. 创建聊天前端:

chat/templates中创建chat.html,前端与后端通过WebSocket进行交互。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Django WebSocket Chat</title>
    <script>
        const chatSocket = new WebSocket('ws://' + window.location.host + '/ws/chat/');

        chatSocket.onmessage = function(e) {
            const data = JSON.parse(e.data);
            document.querySelector('#messages').innerHTML += '<div>' + data.message + '</div>';
        };

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

        document.querySelector('#message-input').focus();
        document.querySelector('#message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // Enter key
                const messageInputDom = document.querySelector('#message-input');
                const message = messageInputDom.value;
                chatSocket.send(JSON.stringify({ 'message': message }));
                messageInputDom.value = '';
            }
        };
    </script>
</head>
<body>
    <h1>Django WebSocket Chat</h1>
    <div id="messages"></div>
    <input id="message-input" type="text" placeholder="Type a message...">
</body>
</html

>
3.3 运行Django应用
python manage.py runserver

访问http://127.0.0.1:8000/可以看到聊天界面,多个浏览器标签页同时访问时,输入的消息会实时显示。

四、总结

WebSocket为现代Web应用提供了实时通信的能力,Flask和Django都能非常便捷地集成WebSocket功能。在Flask中,我们通过Flask-SocketIO来处理WebSocket,而在Django中,则可以通过Django Channels来实现。无论是Flask还是Django,都能轻松搭建一个高效的实时聊天系统。

选择哪种框架主要取决于你的项目需求。如果你已经在使用Flask且需要一个轻量级的聊天系统,Flask-SocketIO是一个不错的选择。而对于大型的Django应用,Django Channels提供了更强大、可扩展的解决方案。希望本文的示例能帮助你在自己的项目中实现实时聊天功能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「Mac畅玩鸿蒙与硬件50」UI互动应用篇27 - 水果掉落小游戏

本篇教程将带你实现一个水果掉落小游戏&#xff0c;掌握基本的动态交互逻辑和鸿蒙组件的使用&#xff0c;进一步了解事件处理与状态管理。 关键词 UI互动应用水果掉落状态管理动态交互游戏开发 一、功能说明 水果掉落小游戏包含以下交互功能&#xff1a; 随机生成水果&#…

C# OpenCV机器视觉:凸包检测

在一个看似平常却又暗藏玄机的午后&#xff0c;阿强正悠闲地坐在实验室里&#xff0c;翘着二郎腿&#xff0c;哼着小曲儿&#xff0c;美滋滋地品尝着手中那杯热气腾腾的咖啡&#xff0c;仿佛整个世界都与他无关。突然&#xff0c;实验室的门 “砰” 的一声被撞开&#xff0c;小…

UGUI 优化DrawCall操作记录(基于Unity2021.3.18)

UGUI中相同材质相同Shader相同贴图的UI元素可以合并DrawCall。 1.使用图集 Unity性能优化---使用SpriteAtlas创建图集进行批次优化_unity2021.3.33 spriteatlas优化-CSDN博客 2.Canvas的子物体在场景树中的索引位置和不同图集不影响UI合批且UI网格没有重叠&#xff0c;如下图…

3---杭州工作三年半

2021-07-06来杭——2025-01-01元旦 1滨江2021-07-06——2022-11-25&#xff08;一年零四个月&#xff09; 2下沙2023-01-01——2023-04-27&#xff08;五个月&#xff09; 3苏州2023-06-07——2023-06-27&#xff08;一个月&#xff09;厦门2023-06-29——2023-07-06&#xff…

【项目开发】C#环境配置及VScode运行C#教程(学生管理系统)

原创文章,禁止转载。 文章目录 下载.NETVScode配置运行程序下载.NET 官网链接: https://dotnet.microsoft.com/en-us/download选择任意版本下载: 下载完成后,双击运行exe文件,等待安装完成。 在控制台输入: dotnet --version若出现版本信息,说明安装成功: VScode配…

Excel文件恢复教程:快速找回丢失数据!

Excel文件恢复位置在哪里&#xff1f; Excel是微软开发的电子表格软件&#xff0c;它为处理数据和组织工作提供了便捷。虽然数据丢失的问题在数字时代已经司空见惯&#xff0c;但对于某些用户来说&#xff0c;恢复未保存/删除/丢失的Excel文件可能会很困难&#xff0c;更不用说…

亚矩阵云手机技术形态与应用方向

亚矩阵云手机技术架构 亚矩阵云手机技术架构深度融合了云计算、虚拟化、边缘计算和大数据等先进技术&#xff0c;构建了一个全面且高效的移动终端服务体系。其中&#xff0c;云端服务器作为整个云手机的基石&#xff0c;采用高性能、高可用性的云计算资源&#xff0c;负责提供海…

3D线上艺术展:艺术与技术的完美融合

随着数字技术的飞速发展&#xff0c;未来的艺术展览正逐步迈向线上线下融合的新阶段。其中&#xff0c;3D线上展览以其独特的魅力&#xff0c;成为线下展览的延伸与拓展&#xff0c;为艺术爱好者们开辟了全新的观赏途径。 对于艺术家和策展人而言&#xff0c;3D线上展览不仅打…

ES elasticsearch-8.17.0-windows-x86_64使用

1、下载ES(elasticsearch 简称 ES 下载链接&#xff1a;https://www.elastic.co/downloads/elasticsearch) ES 下载链接&#xff1a;https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.17.0-windows-x86_64.zip))&#xff0c;需要在修改ES配置&#xff0…

sqlserver设置定时任务计划(SSMS)

软件&#xff1a;SQL Server Management Studio&#xff08;SSMS&#xff09; 1.连接数据库服务器&#xff0c;找到 SQL Sever Agent&#xff08;代理&#xff09; 启动 2.启动后&#xff0c;点开 Jobs&#xff08;作业&#xff09; 新建&#xff0c;填写常规信息 3.步骤 > …

如何规范的提交Git?

多人协作开发提交代码通常是遵循约定式提交规范&#xff0c;如果严格安照约定式提交规范&#xff0c; 手动进行代码提交的话&#xff0c;那么是一件非常痛苦的事情&#xff0c;但是 Git 提交规范的处理又势在必行&#xff0c;那么怎么办呢&#xff1f; 经过了很多人的冥思苦想…

WPF编程excel表格操作

WPF编程excel表格操作 摘要NPOI安装封装代码测试代码 摘要 Excel操作几种方式 使用开源库NPOI(常用&#xff0c;操作丰富)使用Microsoft.Office.Interop.Excel COM组件(兼容性问题)使用OpenXml(效率高)使用OleDb(过时) NPOI安装 封装代码 using System; using System.IO; u…

初识 Conda:一站式包管理和环境管理工具

文章目录 1. 什么是 Conda&#xff1f;2. 为什么选择 Conda&#xff1f;3. Conda 的安装3.1 安装步骤&#xff08;以 Miniconda 为例&#xff09; 4. Conda 的核心功能4.1 包管理4.2 环境管理4.3 Conda Forge4.4 设置国内镜像 5. 常见使用场景5.1 数据科学项目5.2 离线安装5.3 …

docker 搭建集群

准备3台机器&#xff1a; #dockermaster 192.168.31.150 sudo hostnamectl set-hostname dockermaster #初始化主节点 docker swarm init --advertise-addr 192.168.31.150 #查看集群是否搭建成功 docker node ls #dockernode1 192.168.31.151 sudo hostnamectl set-hostname …

Kafka消息不丢失与重复消费问题解决方案总结

1. 生产者层面 异步发送与回调处理 异步发送方式&#xff1a;生产者一般使用异步方式发送消息&#xff0c;异步发送有消息和回调接口两个参数。在回调接口的重写方法中&#xff0c;可通过异常参数判断消息发送状态。若消息发送成功&#xff0c;异常参数为null&#xff1b;若发…

StarRocks 存算分离在得物的降本增效实践

编者荐语&#xff1a; 得物优化数据引擎布局&#xff0c;近期将 4000 核 ClickHouse 迁移至自建 StarRocks&#xff0c;成本降低 40%&#xff0c;查询耗时减半&#xff0c;集群稳定性显著提升。本文详解迁移实践与成果&#xff0c;文末附丁凯剑老师 StarRocks Summit Asia 2024…

微服务-1 认识微服务

目录​​​​​​​ 1 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 2 服务拆分原则 2.1 什么时候拆 2.2 怎么拆 2.3 服务调用 3. 服务注册与发现 3.1 注册中心原理 3.2 Nacos注册中心 3.3 服务注册 3.3.1 添加依赖 3.3.2 配置Nacos 3.3.3 启动服务实例 …

IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具

文章目录 一、IDEA二、建立第一个 Java 程序三、IDEA 常用设置四、IDEA 集成版本控制工具&#xff08;Git、GitHub&#xff09;4.1 IDEA 拉 GitHub/Git 项目4.2 IDEA 上传 项目到 Git4.3 更新提交命令 一、IDEA 1、什么是IDEA&#xff1f; IDEA&#xff0c;全称为 IntelliJ ID…

kafka开机自启失败问题处理

前言&#xff1a;在当今大数据处理领域&#xff0c;Kafka 作为一款高性能、分布式的消息队列系统&#xff0c;发挥着举足轻重的作用。无论是海量数据的实时传输&#xff0c;还是复杂系统间的解耦通信&#xff0c;Kafka 都能轻松应对。然而&#xff0c;在实际部署和运维 Kafka 的…

二维数组综合

第1题 稀疏矩阵 查看测评数据信息 nm矩阵大部分元素是0的矩阵称为稀疏矩阵&#xff0c;假设有k个非0元素&#xff0c;则可把稀疏矩阵用K3的矩阵简记之&#xff0c;其中第一列是行号&#xff0c;第二列是列号&#xff0c;第三列是该行、该列下的非0元素的值。如&#xff1a;…