Flask框架-1-[群聊]: flask-socketio实现websocket的功能

news2024/11/24 6:07:14

一、项目结构

flask_websocket

        |---static

                |---js

                        |---jquery-3.7.0.min.js

                        |---socket.io_4.3.1.js

        |---templates

                |---home

                        |---group_chat.html

                        |---index.html

        |---app.py

1.1、python环境

python3.9.0

1.2、依赖包

Flask==2.1.0
eventlet==0.33.3
Flask-SocketIO==5.3.4

1.3、js文件下载

https://code.jquery.com/jquery-3.7.0.min.js

https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.min.jsicon-default.png?t=N7T8https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.min.js

二、非群聊功能

概述:项目中使用websocket,无法是为了实现实时更新数据。在某些数据上,需要能够实时更新数据或需要服务端主动向客户端推送更新的数据。

2.1、前端index.html

<!DOCTYPE html>
<html>
<head>
    <script src="/static/js/socket.io_4.3.1.js"></script>
    <script src="/static/js/jquery-3.7.0.min.js"></script>
    <script type="text/javascript">

        var socket = io({
        query:{
            'token':'123456'
        }
        });
         // 1、接收服务器端,给connect事件的响应,token验证成功服务器端才允许连接
        socket.on('success', function(message) {
            // 处理从服务器接收到的响应数
            alert(message)
        });

        //2、 接收来自服务器的'handle_data'事件,返回的数据
        socket.on('handle_data', function(message) {
             console.log(message)
            // 处理从服务器接收到的响应数
            const msg = message.msg;
            const $showDiv = $('#show');
            const pElement = $('<p>').text(msg);
            //添加到展示的div标签中
            $showDiv.append(pElement);
        });



        //3、 发送'handle_data'事件给服务器d
        function sendMessage() {
            var message = {"type":"user","id":1};
            //向后端获取id=1的用户的数据
            socket.emit('handle_data',message); //可以直接返回字典等数据

        }
    </script>
</head>
<body>
    <div id="show">

    </div>
    <button onclick="sendMessage()">Send Message</button>

</body>
</html>

2.2、后端相关接口,app.py

from flask import Flask,render_template,request,jsonify
from flask_socketio import SocketIO,send,emit,join_room

app = Flask(__name__,static_folder='./static',template_folder='./templates')
socketio = SocketIO(app,cors_allowed_origins='*')

'''
一、非群聊功能,前端需要实时更新某些数据使用
1、返回html页面
2、主动发送websocket到后端,后端返回数据给请求的用户
3、调用某个视图函数,在视图函数中,给所有连接推送新的数据
'''

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

@app.route('/user')
def user():
    # 给房间名中的所有websocket,广播数据,告知所有连接去获取新的数据,
    socketio.emit('handle_data', {'data': '返回的数据', 'type': 'user', 'msg': '数据更新,广播到房间中返回的数据'}, room='default')
    return jsonify({'code': 200, 'data':'update data success!!!'})

@socketio.on('handle_data')
def handle_data(data):
    print(data,'接收浏览器发送的数据')
    #1、给发送给后端的websocket,发送数据,单独给这个websocket发送
    # socketio.emit('handle_data', {'data':'返回的数据','type':'user','msg':'单独返回'})
    emit('handle_data',{'data':'返回的数据','type':'user','msg':'主动请求时,返回的数据'})


@socketio.on('connect')
def handle_connect():
    print('connect连接')
    token = request.args.get('token')
    sid = request.sid
    print(request.args,'args')
    # print('连接的sid',request.sid)

    if token == '123456':
        socketio.emit('success','验证token成功')
        join_room('default') #加入到默认的房间中了
        #表明连接成功
    else:
        print('token验证失败')
        #阻止连接
        return False

if __name__ == '__main__':
    socketio.run(app,debug=True)

2.3、功能测试

1、访问:http://127.0.0.1:5000 ,在发起连接时,传递了token,token验证成功才能建立连接

2、点击 Send Message,模拟前端主动向后端发送信息,如获取指定数据,后端再返回指定数据

3、新开一个标签访问:http://127.0.0.1:5000/user,模拟操作某些接口后,数据发生了变化,服务端主动将更新后的数据发给前端

三、群聊功能

概述:在web端实现群聊功能,实时收发消息。

3.1、前端group_chat.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>群聊</title>
    <script type="application/javascript" src="/static/js/jquery-3.7.0.min.js"></script>
    <script type="application/javascript" src="/static/js/socket.io_4.3.1.js"></script>
    <script type="application/javascript">
        //传递给模板的数据,转成python数据结构
        const data = {{ data|tojson }};
        const group = data.group; //群名
        const name = data.name;//当前用户名
        //1、发起连接
        const socket = io('http://'+document.domain+':'+location.port+'/chat',
            {query:{'token':'123456','group':group,'name':name}}
        );


        //2、监控群里中的消息
        socket.on('group_recv',function (data) {
            const msg = data.msg; //群里的消息
            const sendName = data.name; //发消息的人
            const sendType = data.type; //消息的类型
            const showDiv = $('#showDataId'); //展示消息的区域
            console.log(data)
            if (sendType==='connect'){
                //有人进入群里
                if (name===sendName){
                    const pElement = $('<p>').text('欢迎您进入 '+group+' 群聊....');
                    //添加到展示的div标签中
                    showDiv.append(pElement);
                }else {
                    const pElement = $('<p>').text('热烈欢迎'+sendName+'进入群聊....');
                    //添加到展示的div标签中
                    showDiv.append(pElement);
                }

            }else if (sendType==='data'){
                //有人群里发消息
                if (name===sendName){
                    const pElement = $('<p>').text(msg);
                    //添加到展示的div标签中
                    showDiv.append(pElement);
                } else {
                    const pElement = $('<p>').text(sendName+'> '+msg);
                    //添加到展示的div标签中
                    showDiv.append(pElement);
                }
            }else {
                //有人退出群里
                if (name === sendName) {

                } else {
                    const pElement = $('<p>').text('公告: ' + sendName + '退出群里...');
                    //添加到展示的div标签中
                    showDiv.append(pElement);
                }
            }

        });

        //3、发送消息
        function sendDataFunc() {
           const $sendData = $('#sendDataId');
           socket.emit('group',{'group':group,'msg':$sendData.val(),'name':name});
        }

    </script>
</head>
<body>

{#1、展示群聊的消息#}
<div id="showDataId">

</div>

{#2、发送消息的输入框#}
<div>
    <input id="sendDataId" type="text">
    <input type="button" value="发送消息" onclick="sendDataFunc()">
</div>

</body>
</html>

3.2、后端相关接口

from flask import Flask,render_template,request,jsonify
from flask_socketio import SocketIO,send,emit,join_room

app = Flask(__name__,static_folder='./static',template_folder='./templates')
socketio = SocketIO(app,cors_allowed_origins='*')

''' 
二、群聊相关的:使用名称空间=/chat 
1、返回html页面的,地址栏中提取用户名和群名
2、后端接收js发送的消息,给群广播消息
'''
@app.route('/group/chat')
def group_chat():
    group = request.args.get('group')
    name = request.args.get('name')
    return render_template('home/group_chat.html',data={'group':group,'name':name})

@socketio.on('connect',namespace='/chat')
def chat_connect():
    '''
    控制群里用户进入群连接
    :return:
    '''
    token = request.args.get('token')
    name = request.args.get('name')
    group = request.args.get('group')
    print('群聊的连接:',request.args)
    if token:
        join_room(group)
        emit('group_recv',{'name':name,'msg':f'进入’{group}‘群聊','type':'connect'},room=group)
    else:
        return False

@socketio.on('group',namespace='/chat')
def handle_group(data):
    '''
    :param data: 用户在群聊中发送消息
    :return:
    '''
    print('chat群里发消息:',data)
    group = data.get('group')
    msg = data.get('msg')
    name = data.get('name')
    ret_data = {'msg':msg,'name':name,'type':'data'}
    emit('group_recv',ret_data,room=group)



if __name__ == '__main__':
    socketio.run(app,debug=True)

3.3、功能测试

1、新开一个标签,访问:http://127.0.0.1:5000/group/chat?group=chat1&name=lhz

2、新开一个标签,访问: http://127.0.0.1:5000/group/chat?group=chat1&name=yf

3、新开一个标签,访问:http://127.0.0.1:5000/group/chat?group=chat1&name=zzh

4、在任意一个输入框中输入信息并发送

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

温习JAVA

1.时间 作业题&#xff1a; 1.子串在字符串中出现的次数 import java.util.Scanner;/*** 分别在控制台输⼊字符串和⼦字符* 串&#xff0c;并计算字符串中⼦字符串出现的* 次数。indexOf(subs,n)*/ public class H5 {public static void main(String[] args) {Scanner scnew …

linux搭建单机ES,集成ik分词器,文本抽取,Kibana可视化平台

Elasticsearch单机&#xff08;Linux&#xff09; 准备工作 第一项&#xff1a; 创建运行Elasticsearch和Kibana专用的普通用户&#xff0c;因为 elasticsearch 和 kibana 不允许使用 root用户启动&#xff0c;所以需要创建新用户启动。 linux用root权限创建一个用户赋权即可…

BootStrap中的布局

1.BootStrap中的布局 2.BootStrap 中的媒体查询 // Extra small devices (portrait phones, less than 576px) media (max-width: 575px) { ... }// Small devices (landscape phones, 576px and up) media (min-width: 576px) and (max-width: 767px) { ... }// Medium dev…

38 | 统一测试数据平台

测试数据准备的 2.0 时代 在Java中可以利用Builder Pattern&#xff0c;创建数据时如对其中的某个或某几个参数有特定要求的话&#xff0c;可以通过“.withParameter()”的方式指定&#xff0c;而没有指定的参数将自动采用默认值。 UserBuilder.withCountry(“US”).withBuild…

深度学习-ONNX模型

ONNX&#xff08;Open Neural Network Exchange&#xff09;是一种开放的、跨平台的模型交换格式&#xff0c;旨在帮助机器学习开发人员轻松地在不同的深度学习框架之间共享模型。 ONNX是由Microsoft和Facebook合作推出的&#xff0c;它使得不同深度学习框架之间可以相互转换模…

036:vue导出页面生成pdf文件

第036个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Git:利用Git进行多人协作的场景模拟

文章目录 场景一场景二解决一些后续问题 场景一 Git是一个多人协作下完成的操作&#xff0c;因此Git是需要进行一些多人协作的场景的&#xff0c;那么这里就使用Linux和Windows两个平台进行模拟实现两个用户进行的协作 首先把仓库克隆到本地&#xff0c;再加入两个用户的信息…

软件设计模式系列之十——组合模式

1 模式的定义 组合模式是一种结构型设计模式&#xff0c;用于将对象组合成树形结构以表示部分-整体层次结构。这个模式允许客户端以一致的方式处理单个对象和对象组合&#xff0c;因此它将单个对象和组合对象视为可互换的。 组合模式允许你将对象组合成树状结构来表示"部…

AI写作宝-为什么要使用写作宝

写作一直是一项需要创造力和思考的任务&#xff0c;人工智能&#xff08;AI&#xff09;正逐渐成为我们写作过程中的一位新伙伴。AI写作宝等在线AI写作工具正日益普及&#xff0c;为我们提供了更多的写作选择和可能性。 AI写作宝&#xff1a;什么是它们&#xff0c;以及它们能做…

国庆节都有哪些营销方案?

这里分享一些撰写国庆节营销方案的方法论&#xff0c;同时分享一些常见的国庆节营销方式。 1、确定活动时间&#xff1a; 一般来讲&#xff0c;国庆活动的最好时间是9月29日-10月7日&#xff0c;前期需要留有预热宣传的时间&#xff0c;告知用户活动的主题以及福利政策 2、确…

媒体发稿的步骤与技巧:打造品牌曝光与声誉

媒体发稿是企业、组织和个人获取曝光和传播信息的重要途径之一。通过媒体发稿&#xff0c;可以向目标受众传递重要的信息、推广产品或服务、塑造品牌形象等。然而&#xff0c;对于许多人来说&#xff0c;媒体发稿的流程和步骤可能会感到复杂和困惑。本文将为您介绍媒体发稿的基…

怒刷LeetCode的第7天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;二分贪心 方法二&#xff1a;二分DP 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;双指针 方法二&#xff1a;暴力搜索 方法三&#xff1a;排序 第三题 题目来源 题目内容 解决方法 方法一…

【算法】单调栈

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

“高级Java注解的简介及应用“

目录 引言1. Java注解简介1.1 什么是注解1.2 注解的作用1.3 常见的Java注解 2. 自定义注解案例3. AOP自定义注解的应用3.1 AOP简介3.2 AOP自定义注解 总结 引言 在Java开发中&#xff0c;注解是一种非常重要的语言特性&#xff0c;它们可以为代码提供额外的信息和元数据。本文…

MFC 绘图

效果图&#xff1a;三张bmp图 字 竖线 组成 在OnPaint()函数中 CPaintDC dc(this);CRect rect;GetClientRect(&rect); //获取客户区矩形CDC dcBmp; //定义并创建一个内存设备环境dcBmp.CreateCompatibleDC(&dc); //创建兼容性DCCBitmap …

如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件

目录 1. 修改源码&#xff0c;让模型能够生成出对于单个图像的标注。 2. 把数据转为yolo格式 3.把yolo格式转化为xml格式 这两天想偷懒&#xff0c;想让模型先在数据上标一遍&#xff0c;然后我再做修正&#xff0c;主要是图个省事。由于我们主要是利用paddle,模型也是基于p…

python+django学习资料在线分享系统vue

本站是一个B/S模式系统&#xff0c;采用vue框架作为开发技术&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得校园资料分享平台管理工作系统化、规范化。技术栈 后端&#xff1a;pyth…

同城信息服务源码 本地生活服务小程序源码

同城信息服务源码 本地生活服务小程序源码 功能介绍&#xff1a; 基本设置&#xff1a;网站参数、安全设置、分站管理、支付设置、操作日志、地区设置、公交地铁、国际区号、清理缓存、模板风格、模块管理、域名管理、底部菜单、消息通知、登录设置 其他设置&#xff1a;关键…

Linux内核源码分析 (B.7)深入理解 slab cache 内存分配全链路实现

Linux内核源码分析 (B.7)深入理解 slab cache 内存分配全链路实现 文章目录 Linux内核源码分析 (B.7)深入理解 slab cache 内存分配全链路实现1\. slab cache 如何分配内存2\. slab cache 的快速分配路径3\. slab cache 的慢速分配路径3.1 从本地 cpu 缓存 partial 列表中分配3…

小程序多种姿势更换文章

概述 简单的文章切换demo&#xff0c;通过倒计时、摇一摇、双击进行文章切换 详细 直接看效果图吧&#xff01;比较简单&#xff0c;主要是练习一下... 小程序不带双击事件&#xff0c;可以记录第一次单击事件和第二次单机事件进行双击操作。 1、摇一摇是通过调用官方的 …