使用 python flask 的异步服务器消息

Fir*_*300 7 javascript python flask socket.io

我正在尝试将服务器消息推送给登录到我们的 Flask 网站的最终用户。

我做了一些研究,似乎最好的解决方案是使用 socket-io。

我在这方面的尝试似乎不起作用,我还必须表明我对 javascript 的了解非常基础。

任何帮助/指导将不胜感激。

请参阅下面的代码:

蟒蛇-app.py

from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, request
from time import sleep

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['DEBUG'] = True

# turn the flask app into a socketio app
socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if request.form['submit_button'] == 'Do Stuff':
            # server doing things....
            # the below method will make calls to emit socket messages
            # based on actions / outcome of actions.
            serverActions()
    return render_template('index.html')

@socketio.on('connect')
def connect():
    print('Client connected')

@socketio.on('display_message')
def displayMessage(message):
    socketio.emit('newmessage', {'message': message})
    socketio.sleep(2)

def serverActions():
    # get connection to DB
    message = "connecting to DB"
    # show message to user on flask page
    displayMessage(message)

    # test successful connection to DB
    message = "successfully connected to DB"
    displayMessage(message)

    # query the DB
    message = "querying the DB"
    displayMessage(message)

    # update DB
    message = "updating the DB"
    displayMessage(message)

    # etc......

if __name__ == '__main__':
    socketio.run(app)
Run Code Online (Sandbox Code Playgroud)

HTML - 模板/index.html

<!DOCTYPE html>
<html>
<head>
    <script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
    <script src="static/js/application.js"></script>
</head>
<body>
  <form method="POST">
  <div>
    <div>
      <h1>Asynchronous Flask Communication</h1>
      <p>Messages generated by the Flask server should appear below, asynchronously.</p>
    </div>
  </div>

  <div>
      <p>Asynchronous page updates will appear here:</p>
      <div>
        <input type="submit" value="Do Stuff" name="submit_button">
      </div>
      <div>
        <h3>Server Messages:</h3>
        <div id="message">
        </div>
      </div>
  </div>

  </form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

javascript - 静态/js/application.js

$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://' + document.domain + ':' + location.port);

    //receive message details from server
    socket.on('display_message', function(msg) {
        console.log("Received message" + msg.message);
        message_string = '<p>' + msg.message + '</p>';
        $('#message').html(message_string);
    });

});
Run Code Online (Sandbox Code Playgroud)

C.G*_*hev 7

emit使用on事件处理程序侦听的事件。此外,我认为您的事件侦听器display_message位于休息端点内是没有意义的。这是一个pypubsub为方便起见的解决方案,因此您可以轻松订阅服务器上的所有事件。它也可以在没有它的情况下工作,但在这里

服务器.py

from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, request
from time import sleep
from pubsub import pub


app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['DEBUG'] = True

# turn the flask app into a socketio app
socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

def listener(arg1):
    print('Function listener1 received:')
    print('  arg1 =', arg1)
    socketio.emit('newmessage',{'message':arg1})


pub.subscribe(listener, 'rootTopic')

@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')

@app.route('/post', methods=['POST'])
def post():
    pub.sendMessage('rootTopic', arg1='post')

@socketio.on('connect')
def connect():
    pub.sendMessage('rootTopic', arg1='connected to socket')
    print('Client connected')



if __name__ == '__main__':
    socketio.run(app)
Run Code Online (Sandbox Code Playgroud)

索引.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="message"></div>
    <button id="btn">CLICK</button>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://' + document.domain + ':' + location.port);
    $('#btn').on('click', function() {
      fetch('http://' + document.domain + ':' + location.port + '/post', {method:"POST"})
    })
    //receive message details from server
    socket.on('newmessage', function(msg) {
        console.log("Received message" + msg.message);
        message = '<p>' + msg.message + '</p>';

        $('#message').append(message);
    });

});
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

  • 我认为你把事情过于复杂化了。当这些服务器操作发生时,只需“发出”它们即可。此外,在路由范围内也不会连接到数据库,只需在相应消息发生事件时调用“sendMessage”,并在需要时使用“async”“await”。我认为不需要你的函数 `serverActions` 。 (2认同)
  • 这听起来像是我可以使用的东西。一个例子将非常有帮助和赞赏。预先感谢您。 (2认同)