尽管使用了 socketio.run(),但“Flask-SocketIO 正在 Werkzeug 下运行”

Posted

技术标签:

【中文标题】尽管使用了 socketio.run(),但“Flask-SocketIO 正在 Werkzeug 下运行”【英文标题】:"Flask-SocketIO is Running under Werkzeug" despite using socketio.run() 【发布时间】:2021-06-30 13:44:17 【问题描述】:

尽管使用了 socketio.run(),但我在使用 Eventlet 运行 Flask 和 SocketIO 时遇到了问题,欢迎提出任何建议。我目前使用的是 Python 3.9,我已经尝试了每个模块的多个不同版本,但无济于事。

[2021-04-04 06:39:05,709] WARNING in __init__: Flask-SocketIO is Running under Werkzeug, WebSocket is not available.
"GET /socket.io/?EIO=4&transport=websocket HTTP/1.1" 400 -

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SAR</title>
    <script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>
</head>
<body>

<button id="ping" onclick="send()">ping</button>

<script>
    var socket = io.connect("http://" + document.domain + ":" + location.port, transports: ['websocket']);

    socket.on("connect", function()
        socket.emit("ping", "Established a connection, pinging!");
    );

    socket.on("pong", function(response)
        console.log(response)
    );

    function send()
        socket.emit("ping", "ping_data");
    
</script>

</body>
</html>

app.py

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

app = Flask(__name__)
socketio = SocketIO(app, logger=True)

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

def receivedCallback():
  print('Pong received by user!')

@socketio.on( 'ping' )
def handle_ping(data):
  print("received", data)
  socketio.emit('pong', "pong_data", callback=receivedCallback)

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

【问题讨论】:

【参考方案1】:

大致了解它为何与python app.py 一起运行是if __name__ == '__main__' 仅在通过终端运行时才会执行,就像在许多其他编程语言中首先调用main 函数一样直接从终端运行时使用 Java 或 C。

当通过 Werkzeug 运行 Flask 应用程序时,Flask 应用程序实例被导入并由 Werkzeug 包装到一个模块中,请求被路由到该模块中。 (这就是为什么if __name__ == __main__ 部分永远不会执行的原因——就像您在代码中导入另一个模块时,该模块的主要函数永远不会被调用。)所以,据我了解,当您运行您的 Flask 应用程序时通过 Werkzeug,请求默认通过 HTTP 接收和路由,而不是通过运行 socketio.run() 时 Flask-SocketIO 使用的 WebSocket 协议。 WebSocket 协议要求套接字始终处于打开状态,从而启用异步 I/O,因为它是客户端-服务器协议,所以无法在 HTTP 中工作。

然而,我不知道如何解决问题并通过 Werkzeug 使用 Flask-SocketIO,但我希望上述解释能够对您的问题有所启发,并引导您朝着正确的方向前进。

【讨论】:

【参考方案2】:

似乎通过终端运行我的主文件可以解决此问题。如果有人知道这是为什么,请分享,谢谢。 :)

python app.py

【讨论】:

以上是关于尽管使用了 socketio.run(),但“Flask-SocketIO 正在 Werkzeug 下运行”的主要内容,如果未能解决你的问题,请参考以下文章

在线程中运行 flask-socketio

在 Flask-SocketIO 上使用 ssl 设置 ping_timeout

我在窗口中有一个 fltk Fl_Choice 下拉菜单,但只能通过鼠标使用

尽管使用了工作区,但 Azure Pipeline '没有这样的模块'

FLTK:Fl_Value_Input 子类不接收 FL_KEYDOWN 事件(仅 FL_KEYUP)

尽管使用了 if 语句,但 RelatedObjectDoesNotExist 错误