如何从Flask服务器(Python)向HTML客户端发送消息?

6
为了练习,我正在尝试让Flask服务器不断地向HTML页面的控制台打印“Hello”。但是我目前不知道该如何继续。
目前,我的服务器代码大致如下:
app = Flask(__name__)
 app.config['SECRET_KEY'] = 'secret!'
 socketio = SocketIO(app)

@socketio.on('message')
 def handle_message(message):
    print('Message: ' + message)
     send(message)

@socketio.on('json')
 def handle_json(json):
    send(json, json=True)

@socketio.on('my event')
  def handle_my_custom_event(json):
     emit('my response', json, broadcast=True)

def hello():
    emit('message', {'hello':"Hello"})

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

if __name__ == '__main__':
     socketio.run(app)
     while True:
          hello()

我的客户端代码看起来像这样:

<head>
      <script type="text/javascript" charset="utf-8">
            var socket = io.connect('http://' + document.domain + ':' + location.port);
            socket.on('connect', function() {
                 socket.emit('connected');
            });
            socket.on('message', function(data) {
                 console.log(data);
            });
      </script>
</head>

但是我在控制台日志中没有看到页面的任何内容。我应该如何让Flask服务器发送的消息在控制台打印出来?我做错了什么?

我现在明白,它应该打印JSON而不是“Hello”字符串,这也没关系。我只想从服务器上打印一些东西在网页控制台中。

1个回答

12

以下是一个简单的示例,展示了如何连接到SocketIO服务器并在连接后从服务器接收消息。

app.py

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

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


@socketio.on('connect')                                                         
def connect():                                                                  
    emit('message', {'hello': "Hello"})                                         


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


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

模板/index.html

<head>

      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
      <script type="text/javascript" charset="utf-8">
            var socket = io.connect('http://' + document.domain + ':' + location.port);
            socket.on('connect', function() {
                 console.log('connected');
            });
            socket.on('message', function(data) {
                 console.log(data);
            });
      </script>
</head>

编辑:

为了让服务器每五秒钟发送一个SocketIO消息,您可以使用后台线程:

app.py

from flask import Flask, render_template                                        
from flask_socketio import SocketIO, emit                                       
import time                                                                     

app = Flask(__name__)                                                           
app.config['SECRET_KEY'] = 'secret!'                                            
socketio = SocketIO(app)                                                        
thread = None                                                                   


def background_thread():                                                        
    while True:                                                                 
        socketio.emit('message', {'goodbye': "Goodbye"})                        
        time.sleep(5)                                                           


@socketio.on('connect')                                                         
def connect():                                                                  
    global thread                                                               
    if thread is None:                                                          
        thread = socketio.start_background_task(target=background_thread)       


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


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

太棒了!但是我该如何让它定期发送消息呢(比如每5秒钟)? - Jon
通常情况下,服务器只会在发生某些事件时向连接的客户端发送消息。让服务器不断发送相同的消息并没有太多意义。但是,如果您真的想这样做,您可以启动一个后台线程,每五秒钟发出一个socketio消息。 - Matt Healy
谢谢你的帮助!你介意也提供一个例子吗?(我在网上找到了一个例子,尝试了一下,但是无法运行) - Jon
由于某种原因,第二个示例无法正常工作。Python输出停留在“(7134) wsgi starting up on http://127.0.0.1:5000 (7134) accepted ('127.0.0.1', 63548)”处,Web控制台显示“ET http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lhztt_G net::ERR_CONNECTION_REFUSED”。 - Jon
不确定问题出在哪里。这个例子在我的机器上可以运行,所以可能是你的设置/平台上的某些特定问题。 - Matt Healy
1
我不知道为什么,但我不得不添加 "import eventlet eventlet.monkey_patch()",然后它就可以正常工作了!非常感谢您的帮助! - Jon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接