2012-09-01 13 views
37

मैं फ्लास्क माइक्रो-वेब ढांचे पर सर्वर पुश कार्यक्षमता के साथ एक छोटी सी साइट बनाने की कोशिश कर रहा हूं, लेकिन मुझे नहीं पता था कि सीधे काम करने के लिए कोई ढांचा है या नहीं।फ्लास्क ढांचे में सर्वर पुश को कैसे कार्यान्वित करें?

मैंने Juggernaut का उपयोग किया, लेकिन ऐसा लगता है कि वर्तमान संस्करण में redis-py के साथ काम नहीं कर रहा है, और हाल ही में जुगर्नॉट को हटा दिया गया है।

क्या किसी के पास मेरे मामले के साथ कोई सुझाव है?

+6

[यहां पिछले महीने से एक प्रासंगिक लेख है, जो फ्लास्क के मुख्य डेवलपर आर्मीन रोनाकर द्वारा किया गया है।] (Http://lucumr.pocoo.org/2012/8/5/stateless-and-proud/) – dumbmatter

+0

संबंधित: [स्ट्रीमिंग पायथन और फ्लास्क के साथ डेटा] (http://stackoverflow.com/q/13386681/4279) – jfs

उत्तर

75

Server-Sent Events पर एक नज़र डालें। सर्वर-प्रेषित घटनाक्रम ब्राउज़र API है जो आपको अपने सर्वर पर सॉकेट खोलने देता है, अद्यतनों की स्ट्रीम की सदस्यता लेता है। अधिक जानकारी के लिए एलेक्स मैकका ( जुगर्नॉट के लेखक) why he kills juggernaut पर पोस्ट करें और क्यों सरल सर्वर-प्रेषित घटनाएं मैनी मामलों में वेबसाइटों की तुलना में नौकरी के लिए बेहतर टूल हैं।

प्रोटोकॉल वास्तव में आसान है। बस अपने प्रतिक्रिया में mimetype text/event-stream जोड़ें। ब्राउज़र कनेक्शन को खुला रखेगा और अपडेट के लिए सुनेगा। सर्वर से भेजे गए एक ईवेंट data: और निम्न नईलाइन से शुरू होने वाली टेक्स्ट की एक पंक्ति है।

data: this is a simple message 
<blank line> 

यदि आप संरचित डेटा का आदान-प्रदान करना चाहते हैं, तो बस अपने डेटा को जेसन के रूप में डंप करें और जेसन को तार पर भेजें।

एक लाभ यह है कि आप एक अतिरिक्त सर्वर की आवश्यकता के बिना फ्लास्क में SSE का उपयोग कर सकते है। गीथब पर एक साधारण chat application example है जो एक पब/उप बैकएंड के रूप में रेडिस का उपयोग करता है।

def event_stream(): 
    pubsub = red.pubsub() 
    pubsub.subscribe('chat') 
    for message in pubsub.listen(): 
     print message 
     yield 'data: %s\n\n' % message['data'] 


@app.route('/post', methods=['POST']) 
def post(): 
    message = flask.request.form['message'] 
    user = flask.session.get('user', 'anonymous') 
    now = datetime.datetime.now().replace(microsecond=0).time() 
    red.publish('chat', u'[%s] %s: %s' % (now.isoformat(), user, message)) 


@app.route('/stream') 
def stream(): 
    return flask.Response(event_stream(), 
          mimetype="text/event-stream") 

आप उदाहरण अनुप्रयोग चलाने के लिए gunicron उपयोग करने की आवश्यकता नहीं है। बस जब एप्लिकेशन चला सूत्रण का उपयोग सुनिश्चित करें, क्योंकि अन्यथा SSE कनेक्शन अपने विकास सर्वर को अवरुद्ध कर देगा: ग्राहक के पक्ष तुम सिर्फ एक जावास्क्रिप्ट हैंडलर समारोह की जरूरत है जो जब एक नया संदेश बुलाया जाएगा पर

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

सर्वर से धक्का दिया जाता है।

var source = new EventSource('/stream'); 
source.onmessage = function (event) { 
    alert(event.data); 
}; 

सर्वर-से भेजे घटनाक्रम हाल फायरफॉक्स, क्रोम और सफारी ब्राउज़र द्वारा supported हैं। इंटरनेट एक्सप्लोरर अभी तक सर्वर-से भेजे गए इवेंट का समर्थन नहीं करता है, लेकिन संस्करण से 10 में उन्हें समर्थन करने के लिए आशा की जाती है कि पुराने ब्राउज़र

+0

हाय @ पीटरस्मिथ, मैंने इस दृष्टिकोण की कोशिश की, हालांकि, अलर्ट (event.data) कभी प्रकट नहीं होता है। मैं पोर्ट 8000 में अपना फ्लास्क ऐप चलाता हूं और पोर्ट 8001 में पुश करता हूं। इसलिए मैंने "var source = new EventSource ('http: // localhost: 8001/push') रखा है;" और फ्लास्क ऐप में एक पृष्ठ है जो उपयोगकर्ता कुछ पोस्ट कर सकता है। पोस्ट को अन्य सभी उपयोगकर्ताओं द्वारा प्रसारित और प्राप्त किया जाता है। आपके पास कोई विचार है? –

+0

आप एक अलग बंदरगाह पर धक्का क्यों चलाते हैं? एसएसई का एक कारण यह है कि यह आपके ऐप के भीतर सामान्य http पर चलता है। आपने अपने फ्लास्क ऐप्स कैसे चलाए? विकास सर्वर के माध्यम से? क्या आपने थ्रेडेड = ट्रू जोड़ा था? आप कौन सा ब्राउज़र उपयोग कर रहे हैं? –

+0

हाय @ पीटर हाफमैन, मैं फ्लास्क के साथ टर्ननाडो का उपयोग करता हूं। क्या यह संभव है कि मैंने ऐप इंस्टेंस और पुशर इंस्टेंस को टर्ननाडो में एक साथ रखा? अलग हैंडलर कहो? क्या मुझे अभी भी मल्टीथ्रेड सेट करना चाहिए? –

5

के रूप में @peter-hoffmann's answer पर एक फॉलो-अप, मैंने विशेष रूप से सर्वर द्वारा भेजे गए ईवेंट को संभालने के लिए एक फ्लास्क एक्सटेंशन लिखा है। इसे Flask-SSE कहा जाता है, और यह available on PyPI है।यह स्थापित करने के लिए चलाएँ:

$ pip install flask-sse 

आप इसे इस तरह उपयोग कर सकते हैं:

from flask import Flask 
from flask_sse import sse 

app = Flask(__name__) 
app.config["REDIS_URL"] = "redis://localhost" 
app.register_blueprint(sse, url_prefix='/stream') 

@app.route('/send') 
def send_message(): 
    sse.publish({"message": "Hello!"}, type='greeting') 
    return "Message sent!" 

और जावास्क्रिप्ट से घटना धारा से कनेक्ट करने के लिए, यह इस तरह काम करता है:

var source = new EventSource("{{ url_for('sse.stream') }}"); 
source.addEventListener('greeting', function(event) { 
    var data = JSON.parse(event.data); 
    // do what you want with this data 
}, false); 

Documentation is available on ReadTheDocs. ध्यान दें कि आपको पब/सब को संभालने के लिए चल रहे Redis सर्वर की आवश्यकता होगी।

संबंधित मुद्दे