如何在客户端不先使用 python 和 flask 请求的情况下通过 socket-io 发送数据

How can I send data though socket-io without the client requesting first with python and flask

我的目标是让我的 Flask 服务器每三秒或在调用函数时发送客户端数据。为此,我正在使用 SocketIO。但是,根据我正在使用的一些示例代码,似乎我只能在客户端请求后才能发送数据。我不希望客户端必须 'poll' 查找是否有新数据,所以我希望服务器在准备好时推送它。

这是我到目前为止尝试过的方法。 (一些代码是不必要的,因为它是基于一个例子)这应该使用 socketio 每隔几秒将时间推送到客户端。

HTML

<!DOCTYPE HTML>
<html>
<head>
    <title>Socket-Test</title>
    <script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function() {

            namespace = '/test';
            var socket = io(namespace);

           

            socket.on('my_response', function(msg, cb) {
                $('#log').text( $('<div/>').text(msg.data).html());
                if (cb)
                    cb();
            });
            
            
            
        });
    </script>
</head>
<body style="background-color:white;">

    <h1 style="background-color:white;">Socket</h1>
    <div id="time" ></div>
</body>
</html>

Python

import threading
from flask import Flask, render_template, session, copy_current_request_context,request
from flask_socketio import SocketIO, emit, disconnect
from threading import Lock
import time

async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()
clients = []
def update():
    time.sleep(1)
    emit('my_response',
         {'data': time.time},
         room=clients[0])
t=threading.Thread(target=update)



@socket_.on('connect')
def handle_connect():
    print('Client connected')
    clients.append(request.sid)
    t.start()


@app.route('/')
def index():
    
    return render_template('index.html', async_mode=socket_.async_mode)


@socket_.on('my_event', namespace='/test')
def test_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my_response',
         {'data': message['data'], 'count': session['receive_count']})


@socket_.on('my_broadcast_event', namespace='/test')
def test_broadcast_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my_response',
         {'data': time.time},
         broadcast=True)






socket_.run(app,port=8050)

我尝试 运行 但它给我错误 RuntimeError: Working outside of request context.

我按照本教程修复了我的代码:https://www.shanelynn.ie/asynchronous-updates-to-a-webpage-with-flask-and-socket-io/

import threading
from flask import Flask, render_template, session, copy_current_request_context,request
from flask_socketio import SocketIO, emit, disconnect
from threading import Lock
import time

async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()

def update():
    
    time.sleep(1)
    socket_.emit('my_response',
         {'data': time.time()},
        namespace='/test')
    print("emitted")
    update()
t=threading.Thread(target=update)



@socket_.on('connect', namespace='/test')
def handle_connect():
    print('Client connected')
   
    if not t.isAlive():
        t.start()


@app.route('/')
def index():
    
    return render_template('index.html', async_mode=socket_.async_mode)


socket_.run(app,port=8070)

HTML

<!DOCTYPE HTML>
<html>
<head>
    <title>Socket-Test</title>
    <script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function() {

            namespace = '/test';
            var socket = io(namespace);

           console.log(("test"));

            socket.on('my_response', function(msg) {
                $('#time').text( $('<div/>').text(msg.data).html());
                
                console.log(msg);
            });
            
            
            
        });
    </script>
</head>
<body style="background-color:white;">

    <h1 style="background-color:white;">Socket</h1>
    <div id="time" ></div>
</body>
</html>