内置服务:
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()
polling
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()
polling
说明: 长轮询和轮询的区别在于轮询每次由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()
polling Not Connected
说明: 利用gevent-websocket的WebSocketHandler处理类,在服务端调用send()/receive(),可以很方便的实现Websocket客户端与服务端的实时通信,不妨尝试来一发,运维利器网页版tail -f的Websocket实现?