繁体   English   中英

提供实时数据python Web应用程序

[英]Serving real-time data python web application

我正在使用Flask框架,WSGIServer和geventwebsockets编写Python Web应用程序。

我有一个工作线程池进行繁重的处理工作,然后将完成的数据插入MongoDB数据库。 我希望能够在现场向用户显示MongoDB的实时新数据流。

我现在所做的是打开一个套接字连接客户端,每3秒轮询一次MongoDB获取新数据,如下所示:

from flask import Flask
from flask_sockets import Sockets
import datetime

app = Flask(__name__)
sockets = Sockets(app)

@sockets.route('/echo')
def echo_socket(ws):
    last_tweet_printed = datetime.datetime.utcnow() - datetime.timedelta(seconds=55) #start printing tweets from 1 minute ago until catch up.
    while True:
        from database_functions import DatabaseFunctions
        import time
        databaseFunctions = DatabaseFunctions()
        tweets = databaseFunctions.loadTweets() # pulls latest tweets from database (all tweets from last 1 minute)

        limit = 5 # max to print out at once to browser
        index = 0

        for tweet in tweets:
            if(limit != index ):

                if(last_tweet_printed < tweet[u'created_at']): #if the last tweet is older than the one we just pulled...
                    last_tweet_printed = tweet[u'created_at'] #update the latest tweet from db...
                    tweet_text = tweet[u'text']

                    ws.send("<font color=\"blue\">"+tweet_text + "</font><br> <font color=\"red\">" + str(last_tweet_printed) + "</font><br>")

                else:
                    print('no new tweets in database, wait till next poll.\n')

                index+=1
            else:
                break

        print('sleeping...\n')
        time.sleep(3) #sleep for 3 seconds before polling mongoDB again.



@app.route('/')
def hello():
    return  \
'''
<html>
    <head>
        <title>Test Real-Time</title>
        <script type="text/javascript">
            var ws = new WebSocket("ws://" + location.host + "/echo");
            ws.onmessage = function(evt){
                    var received_msg = evt.data;
                    document.getElementById('mark_test').innerHTML += "Tweet: "+received_msg+"<br>";

                    //alert(received_msg);
            };

            ws.onopen = function(){
                ws.send("hello Mark!");
            };
        </script>

    </head>

    <body>
        <h1>Real Time Stream:</h1>
        <div id="mark_test">

        </div>
    </body>

</html>
'''


if __name__ == '__main__':
    from gevent import pywsgi
    from geventwebsocket.handler import WebSocketHandler
    server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
    server.serve_forever()

编写方式有什么限制吗? 是否有更有效/最佳实践的替代方案可以为用户提供更加无缝的流? 我希望应用程序能够处理更多的数据库请求。

您的方法存在两个问题。 一,连接到此Flask服务器的每个客户端分别轮询数据库,因此如果连接了100个客户端,则每3秒进行100次查询。 最好让一个后台线程每3秒轮询一次数据库,并更新其他线程。 echo_socket可以等待每次更新后由后台线程通知的全局Condition变量。

您的代码的另一个问题是,当您进行长轮询时,您将对MongoDB进行短轮询。 长轮询可以降低到达数据库的消息与向用户广播消息之间的延迟, 减少服务器的负载。 考虑一下Rick Copeland关于MongoDB pub / sub的博客文章,寻找灵感。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM