首页 > 代码库 > 基础入门_Python-模块和包.Gevent异步服务类实现多姿势WEB实时展示?

基础入门_Python-模块和包.Gevent异步服务类实现多姿势WEB实时展示?

内置服务:

1. gevent.server.StreamServer类, 常用于创建异步TCP服务器


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
import time
import gevent
from gevent.server import StreamServer
# 说明: 导入其它模块
def tcp_handler(socket, address):
    timestamp = time.strftime(‘%Y-%m-%d %H:%M:%S‘, time.localtime())
    print ‘%s client(%s) connectd to server.‘ % (timestamp, address)
    gevent.sleep(5)
    socket.close()
if __name__ == ‘__main__‘:
    host = ‘‘
    port = 80
    server = StreamServer((host, port), tcp_handler)
    server.serve_forever()

2. gevent.server.DatagramServer类, 常用于创建异步UDP服务器



扩展服务:


1. gevent.server.pywsgi类, 可用于创建支持单向实时轮询服务器, 轮询(polling),浏览器定期发送Ajax请求,服务器收到请求后立马响应且关闭连接

优点: 后端程序编写比较容易

缺点: 请求中大半无用,浪费带宽和服务器资源

实例: 适用于小型应用


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
import time
from gevent.pywsgi import WSGIServer
# 说明: 导入其它模块
def ajax_endpoint(environ, start_response):
    status = ‘200 OK‘
    header = [
        (‘Content-Type‘, ‘text/html‘),
        # 允许跨域
        (‘Access-Control-Allow-Origin‘, ‘*‘)
    ]
    start_response(status, header)
    return str(time.time())
if __name__ == ‘__main__‘:
    host = ‘‘
    port = 80
    server = WSGIServer((host, port), ajax_endpoint)
    server.serve_forever()

<!DOCTYPE html>
<html lang="zh-en">
    <head>
        <meta charset="UTF-8">
        <title>polling</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    </body>
    <script type="text/javascript">
        setInterval(function () {
            $.ajax({
                url: ‘http://127.0.0.1/‘,
                success:function (data) {
                    $(‘body‘).append(‘<p>‘ + data + ‘</p>‘)
                }
            })
        }, 1000)
    </script>
</html>

2. gevent.server.pywsgi类, 可用于创建支持单向实时长轮询服务器, 长轮询(long-polling),客户端向服务器发送Ajax请求,服务器收到请求后hold住连接,直到有消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求

优点: 在无消息的情况下不会频繁的请求,耗费资源小

缺点: 服务器hold连接会消耗资源,返回数据顺序无保证,难以管理维护

实例: WebQQ,Hi网页版,Facebook IM等


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
import time
import gevent
import itertools
from gevent.pywsgi import WSGIServer
from gevent.queue import Queue, Empty
# 说明: 导入其它模块
q = Queue()
def generate_data():
    cycle = itertools.cycle(xrange(1, 101))
    while True:
        q.put_nowait(str(cycle.next()))
        gevent.sleep(5)
def ajax_endpoint(environ, start_response):
    status = ‘200 OK‘
    header = [
        (‘Content-Type‘, ‘text/html‘),
        # 允许跨域
        (‘Access-Control-Allow-Origin‘, ‘*‘)
    ]
    start_response(status, header)
    while True:
        try:
            yield q.get(timeout=1)
        except Empty, e:
            # 队列为空异常返回
            return
if __name__ == ‘__main__‘:
    host = ‘‘
    port = 80
    g = gevent.spawn(generate_data)
    g.start()
    server = WSGIServer((host, port), ajax_endpoint)
    server.serve_forever()
    g.join()

<!DOCTYPE html>
<html lang="zh-en">
    <head>
        <meta charset="UTF-8">
        <title>polling</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    </body>
    <script type="text/javascript">
        function longPolling() {
            $.ajax({
                url: ‘http://127.0.0.1/‘,
                success:function (data) {
                    $(‘body‘).append(‘<p>‘ + data + ‘</p>‘)
                    if(data != ‘100‘) {
                        longPolling()
                    }
                }
            })
        }
        longPolling()
    </script>
</html>

说明: 长轮询和轮询的区别在于轮询每次由Ajax发出请求,服务端处理完毕返回响应后就结束了这条连接,而长轮询由Ajax发出请求,但是发出后会阻塞在那里等待回应,服务端只需要从数据源定期取数据就好,超时后会将之前yied的值一次性返回,本次连接断开,所以返回的数据顺序以及数量是不能保证的.


3. gevent.server.pywsgi+geventwebsocket(pip install gevent-websocket)类, 可用于创建支持双向实时WebSockets服务器,但并不是所有的浏览器都支持WebSockets,个人更推荐socket.io,由于它封装了WebSocket,且支持多种连接方式.


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://xmdevops.blog.51cto.com/
# Purpose:
#
"""
# 说明: 导入公共模块
import time
import gevent
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketError
from geventwebsocket.handler import WebSocketHandler
# 说明: 导入其它模块
def ws_handler(environ, start_response):
    ws = environ["wsgi.websocket"]
    while True:
        try:
            ws.send(str(time.time()))
            gevent.sleep(1)
        except WebSocketError, e:
            pass
if __name__ == ‘__main__‘:
    host = ‘‘
    port = 5000
    server = WSGIServer((host, port), ws_handler, handler_class=WebSocketHandler)
    server.serve_forever()

<!DOCTYPE html>
<html lang="zh-en">
    <head>
        <meta charset="UTF-8">
        <title>polling</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
        <div id="conn_status">Not Connected</div>
        <div id="placeholder" style="width:600px;height:300px;"></div>
    </body>
    <script type="text/javascript">
        $(function () {
            var ws = new WebSocket(‘ws://127.0.0.1:5000‘);
            ws.onmessage = function (event) {
                $(‘#placeholder ‘).append(‘<p>‘ + event.data + ‘</p>‘)
            }
            ws.onopen = function(event) {
                $(‘#conn_status‘).html(‘<b>Connected</b>‘);
            }
            ws.onerror = function(event) {
                $(‘#conn_status‘).html(‘<b>Error</b>‘);
            }
            ws.onclose = function(event) {
                $(‘#conn_status‘).html(‘<b>Closed</b>‘);
            }
        })
    </script>
</html>

说明: 利用gevent-websocket的WebSocketHandler处理类,在服务端调用send()/receive(),可以很方便的实现Websocket客户端与服务端的实时通信,不妨尝试来一发,运维利器网页版tail -f的Websocket实现?


本文出自 “@Can Up and No BB...” 博客,请务必保留此出处http://xmdevops.blog.51cto.com/11144840/1862737

基础入门_Python-模块和包.Gevent异步服务类实现多姿势WEB实时展示?