2019独角兽企业重金招聘Python工程师标准>>>
内置服务:
1. gevent.server.StreamServer类, 常用于创建异步TCP服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/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请求,服务器收到请求后立马响应且关闭连接
优点: 后端程序编写比较容易
缺点: 请求中大半无用,浪费带宽和服务器资源
实例: 适用于小型应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#!/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() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
< 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等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/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() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
< 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,且支持多种连接方式.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#!/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() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
< 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实现?
登录乐搏学院官网http://www.learnbo.com/
或关注我们的官方微博微信,还有更多惊喜哦~
本文出自 “满满李 - 运维开发之路” 博客,请务必保留此出处http://xmdevops.blog.51cto.com/11144840/1862737