You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python Flask实现发送消息后无刷新更新对方客户端

实现Flask实时消息推送(类似WhatsApp网页版效果)

要实现接收方无需刷新页面就能获取新消息的效果,核心是改用WebSocket替代传统HTTP请求实现双向实时通信。下面是基于你的现有代码的改造方案:

1. 依赖安装

使用Flask-SocketIO封装WebSocket功能,同时安装异步服务器提升性能:

pip install flask-socketio eventlet

2. 后端配置与改造

初始化SocketIO

在你的Flask应用入口文件中添加SocketIO初始化:

from flask import Flask
from flask_socketio import SocketIO, emit, join_room

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-existing-secret-key'  # 复用你原来的密钥
socketio = SocketIO(app, cors_allowed_origins="*")  # 跨域设置根据实际场景调整

改造消息发送接口

保留原有的表单提交逻辑,新增WebSocket推送步骤,将新消息实时推送给接收方:

@views.route('/send-msg/<int:id>', methods=['GET', 'POST'])
@login_required
def send_msg(id):
    if request.method == 'POST':
        message = request.form.get('message')
        if len(message) < 1:
            flash('Message is too short!', category='error')
        else:
            new_message = Message(
                data=message, 
                sender_id=current_user.id, 
                receiver_id=id
            )
            db.session.add(new_message)
            db.session.commit()
            
            # 关键:通过SocketIO推送给目标用户
            socketio.emit(
                'new_message',
                {
                    'sender_id': current_user.id,
                    'content': message,
                    'timestamp': new_message.timestamp.strftime('%Y-%m-%d %H:%M:%S')
                },
                room=f'user_{id}'  # 推送给接收方的专属房间
            )
            
            flash('Message sent!', category='success')
    return render_template(
        "message_sender.html", 
        user=current_user, 
        to_contact=Contact.query.get(id)
    )

添加房间监听逻辑

在后端添加用户加入房间的事件处理,确保用户进入聊天页面后能接收专属推送:

@socketio.on('join_room')
def handle_join_room(room):
    join_room(room)

3. 前端页面改造(message_sender.html)

引入SocketIO客户端库

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>

(若禁止外链,可将JS文件下载到本地项目中引入)

添加实时消息处理逻辑

在页面中添加以下脚本,实现SocketIO连接、房间加入、新消息监听与DOM更新:

<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
    // 初始化SocketIO连接
    const socket = io();
    const currentUserId = {{ user.id }};
    
    // 加入当前用户的专属房间,接收发给自己的消息
    socket.emit('join_room', `user_${currentUserId}`);

    // 监听新消息事件,动态更新页面
    socket.on('new_message', function(msgData) {
        const messageContainer = document.getElementById('message-container');
        const newMessage = document.createElement('div');
        // 根据自己的CSS样式调整类名
        newMessage.className = 'message received';
        newMessage.innerHTML = `
            <div class="msg-sender">用户${msgData.sender_id}</div>
            <div class="msg-content">${msgData.content}</div>
            <div class="msg-time">${msgData.timestamp}</div>
        `;
        messageContainer.appendChild(newMessage);
        // 自动滚动到最新消息
        messageContainer.scrollTop = messageContainer.scrollHeight;
    });

    // 拦截表单提交,用AJAX发送避免页面刷新
    const sendForm = document.getElementById('send-form');
    sendForm.addEventListener('submit', function(e) {
        e.preventDefault();
        const msgInput = document.getElementById('msg-input');
        const message = msgInput.value.trim();
        
        if (!message) return;
        
        // 发送消息到后端
        fetch(`/send-msg/{{ to_contact.id }}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: `message=${encodeURIComponent(message)}`
        }).then(() => {
            // 自己发送的消息立即显示到页面
            const messageContainer = document.getElementById('message-container');
            const sentMsg = document.createElement('div');
            sentMsg.className = 'message sent';
            sentMsg.innerHTML = `
                <div class="msg-content">${message}</div>
                <div class="msg-time">${new Date().toLocaleString()}</div>
            `;
            messageContainer.appendChild(sentMsg);
            messageContainer.scrollTop = messageContainer.scrollHeight;
            msgInput.value = '';
        });
    });
});
</script>

注意:需确保页面中的消息容器有message-container ID,表单有send-form ID,输入框有msg-input ID,同时根据你的CSS样式调整消息元素的类名。

4. 启动应用

将原来的app.run()替换为SocketIO的启动方式:

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

核心逻辑说明

  • 房间机制:每个用户对应一个专属房间(如user_123),后端通过房间精准推送消息给目标用户。
  • 双向通信:WebSocket建立后,后端可主动向客户端推送消息,无需客户端轮询。
  • 消息持久化:保留原有的数据库存储逻辑,确保刷新页面后历史消息不丢失。

内容的提问来源于stack exchange,提问作者Asher Brownstein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:32:20