【问题标题】:Long Polling in Python with Flask使用 Flask 在 Python 中进行长轮询
【发布时间】:2015-06-13 13:30:45
【问题描述】:

我正在尝试在 Flask 框架下使用 JQuery 和 Python 进行长轮询。

之前在 PHP 中进行过长轮询,我尝试以同样的方式进行:

具有 while(true) 循环的脚本/函数,定期检查更改,例如每 0.5 秒在数据库中检查一次,并在发生更改时返回一些数据。

所以在我的 ini.py 中,我创建了一个 app.route 到 /poll 以供 JQuery 调用。 JQuery 为它提供有关客户端当前状态的一些信息,并且 poll() 函数将其与数据库中的当前状态进行比较。循环结束并在观察到变化时返回信息。

这是python代码:

@app.route('/poll')
def poll():
client_state = request.args.get("state")

    #remove html encoding + whitesapce from client state
    html_parser = HTMLParser.HTMLParser()
    client_state = html_parser.unescape(client_state)
    client_state = "".join(client_state.split())

    #poll the database
    while True:
        time.sleep(0.5)
        data = get_data()
        json_state = to_json(data)
        json_state = "".join(data) #remove whitespace

        if json_state != client_state:
            return "CHANGE"

问题在于,当上面的代码开始轮询时,服务器似乎已经超载,其他 Ajax 调用以及其他请求(例如使用 JQuery 将“正在加载”的图像加载到 html 中)无响应并超时。

为了完整起见,我在此处包含了 JQuery:

function poll() {

queryString = "state="+JSON.stringify(currentState);

$.ajax({
    url:"/poll",
    data: queryString,
    timeout: 60000,
    success: function(data) {
        console.log(data);
        if(currentState == null) {
            currentState = JSON.parse(data);
        }
        else {
            console.log("A change has occurred");
        }

        poll();

    },
    error: function(jqXHR, textStatus, errorThrown) {

        console.log(jqXHR.status + "," + textStatus + ", " + errorThrown);

        poll();

    }
});

}

这需要多线程吗?或者有谁知道我为什么会遇到这种行为?

提前致谢!! :)

【问题讨论】:

标签: python flask long-polling


【解决方案1】:

正如link @Robᵩ 提到的那样,您的烧瓶应用程序只是过载。这是因为烧瓶应用在使用app.run() 运行时默认处于单线程模式,因此每次只能处理一个请求。

您可以使用以下方式启动多线程:

if __name__ == '__main__':
    app.run(threaded=True)

或者使用像 gunicorn 或 uwsgi 这样的 WSGI 服务器来为烧瓶提供多处理:

gunicorn -w 4 myapp:app

希望您喜欢 Python 和 Flask!

【讨论】:

  • 一般来说,尽管 WSGI 应用程序不适合任何规模的长轮询,尽管这同样适用于 PHP。这是因为 Python 在使用 WSGI 和 PHP 时都是同步系统,需要一个进程或线程来处理每个请求。因此,要处理大量并发的长轮询请求,您需要大量的容量(进程或线程)。长轮询最好使用异步 Web 服务器和框架来实现。
  • 如果使用 gunicorn 的替代方法是通过 eventlet 或 gevent 工作人员使用协程。但是,这样做确实会给您的应用程序带来很多限制,因为您只能将客户端用于支持协程的后端服务和数据库,以避免它们阻塞整个进程。所以协程不仅仅是让一切变得美好的魔法。
  • @GrahamDumpleton 是的,异步服务器希望 Tornado 更好,通常这是我构建 API 或 WebSocket 服务器的首选。
猜你喜欢
  • 1970-01-01
  • 2017-05-15
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
相关资源
最近更新 更多