服务器端推送

Ajax Long Polling

http://zrashwani.com/server-sent-events-example-laravel/#.V0K3j2F961I
http://blog.oddbit.com/2013/11/23/long-polling-with-ja/

(function poll(){
   setTimeout(function(){
      $.ajax({ url: "/path/to/url", success: function(data){
        console.log(data);  
        poll();
      }, dataType: "json"});
  }, 30000);
})();

sse

http://laurat.sinaapp.com/archives/116
http://raising.iteye.com/blog/2272559
http://waylau.com/web-real-time-push-technology/
http://www.cnphp6.com/archives/141974
https://github.com/waylau/rest-in-action/blob/master/docs/Build Real-Time Web App with SSE.md
http://www.html5rocks.com/en/tutorials/eventsource/basics/
http://www.w3school.com.cn/html5/html_5_serversentevents.asp
http://html5doctor.com/server-sent-events/
http://labs.gree.jp/blog/2014/08/11070/
http://stackoverflow.com/questions/9933619/html5-eventsource-listener-for-all-events
http://javascript.ruanyifeng.com/htmlapi/eventsource.html#toc0

python example
http://stackoverflow.com/questions/12232304/how-to-implement-server-push-in-flask-framework
http://mrjoes.github.io/2013/06/21/python-realtime.html
http://pyzh.readthedocs.io/en/latest/python-realtime.html
http://hypatiasoftware.org/2016/01/29/polling-is-a-hack-server-sent-events-eventsource-with-gevent-flask-nginx-and-freebsd/
https://impythonist.wordpress.com/2015/08/02/build-a-real-time-data-push-engine-using-python-and-rethinkdb/
http://www.csdn去除汉字123.com/html/topnews201408/43/10943.htm
https://taoofmac.com/space/blog/2014/11/16/1940

api

# new EventSource(url)
this creates our EventSource object, which immediately starts listening for events on the given URL.

# readyState
as with XHR, we have a readyState for the EventSource that tells us if we’re connecting (0), open (1), or closed (2).

# onopen, onmessage
two events that we can listen for on the new EventSource object. By default, the message event will fire when new messages are received, unless the server explicitly sets the event type.

# addEventListener
not only can we listen for the default message event, but we can also listen for custom messages using the addEventListener on the EventSource object, just as if we were listening for a click event.

# event.data
as with most messaging APIs, the contents of the message reside in the data property of the event object. This is a string, so if we want to pass around an object, we need to encode and decode it with JSON.

# close
closes the connection from the client side.
chat
#!/usr/bin/env python
import datetime
import flask
import redis


app = flask.Flask(__name__)
app.secret_key = 'asdf'
red = redis.StrictRedis()


def event_stream():
    pubsub = red.pubsub()
    pubsub.subscribe('chat')
    # TODO: handle client disconnection.
    for message in pubsub.listen():
        print message
        yield 'data: %s

' % message['data']


@app.route('/login', methods=['GET', 'POST'])
def login():
    if flask.request.method == 'POST':
        flask.session['user'] = flask.request.form['user']
        return flask.redirect('/')
    return '<form action="" method="post">user: <input name="user">'


@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))
    return flask.Response(status=204)


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


@app.route('/')
def home():
    if 'user' not in flask.session:
        return flask.redirect('/login')
    return """
        <!doctype html>
        <title>chat</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <style>body { max- 500px; margin: auto; padding: 1em; background: black; color: #fff; font: 16px/1.6 menlo, monospace; }</style>
        <p><b>hi, %s!</b></p>
        <p>Message: <input id="in" /></p>
        <pre id="out"></pre>
        <script>
            function sse() {
                var source = new EventSource('/stream');
                var out = document.getElementById('out');
                source.onmessage = function(e) {
                    // XSS in chat is fun
                    out.innerHTML =  e.data + '\n' + out.innerHTML;
                };
            }
            $('#in').keyup(function(e){
                if (e.keyCode == 13) {
                    $.post('/post', {'message': $(this).val()});
                    $(this).val('');
                }
            });
            sse();
        </script>
    """ % flask.session['user']


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

simple

server

# -*- coding: UTF-8 -*-
from flask import Flask, Response, render_template
import time

app = Flask(__name__)

#이벤트 스트림을 출력하는 제네레이터 함수.
def event_stream():
    for message in xrange(100):
        # 아래의 sleep은 하지 않아도 무방
        time.sleep(1)
        # SSE의 기본 데이터 프로토콜은 다음과 같다. 다른 형식으로 출력하려면 아래의 하이퍼링크를 참조
        # http://www.html5rocks.com/en/tutorials/eventsource/basics/?redirect_from_locale=ko
        yield 'data: %d

' % message

@app.route('/', methods=['GET'])
def index():
    #render_template함수는 unicode문자열 리턴
    return render_template('index.html')

@app.route('/stream')
def stream():
    #mimetype이 text/event-stream인 파일을 전송하면 SSE성립
    return Response(event_stream(), mimetype="text/event-stream")

if __name__ == '__main__':
    #플래스크 어플리케이션을 쓰레드화 하지 않으면 1개 이상 클라이언트에 대응이 불가능하다.
    app.run(debug=True, threaded=True)

html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script>
        var source = new EventSource('/stream');
        source.onmessage = function (event) {
            document.getElementById('ticker').innerHTML = event.data
            if(event.data == '99'){
                source.close();
                console.log('이벤트 수신 종료')
            }
            console.log(event.data);
        };
    </script>
</head>
<body>
    <div id="ticker">

    </div>
    SSE 서비스 테스트 시작
</body>
</html>
原文地址:https://www.cnblogs.com/liujitao79/p/5491116.html