Gevent的长轮询实现方法详解
长轮询
1.浏览网页时,浏览器会传HTTP 请求到服务器,服务器会根据请求将网页的内容传给浏览器,但是在很多的情况下,使用者会需要看到最新的即时性资讯,例如观看股票市场行情,而在以前只能靠着重新载入网页才能获得最新信息,但是这样不但很浪费时间,也会佔用很多不必要的网络资源,并不是一个好的方式;
2.长轮询就是解决这个问题的一个办法。
什么是长轮询
1.长时间轮询(long-polling)是让服务器在接收到浏览器发出的HTTP 请求后,服务器会等待一段时间,若在这段时间里面伺服器有新的数据更新,它就会把最新的数据传给浏览器,如果等待的时间到了之后也没有新资料的话,就会送一个回应给浏览器,告知浏览器资料没有更新;
2.长时间轮询可以减少产生轮询(polling)造成网路频宽浪费的状况。
浏览器如何长轮询
浏览器向服务器发送Ajax请求,当接收到服务器响应后,需要向服务求发送新的请求。
服务器如何处理长轮询
1.服务器端要能够一直保持住客户端的请求,直到有响应消息;同时服务器对请求的处理要支持非阻塞模式;
2.需要使用Event,python内置Event是阻塞的,gevent的却是非阻塞的。
设计场景
1.浏览器请求获取当前的字符信息,并显示;
2.服务器后天接受某个请求以产生随机字符并存储下来,同时推送给浏览器。
涉及问题
1.服务器需知道浏览器获取信息的标识来推送最新的信息;
2.当浏览器请求更新信息时,服务器可通过Event来保留当前信息,当有新信息来的时候,重设Event来唤醒之前的处理。
实践
html代码
<!doctype html>
<html>
<head>
<title>Long Pooling</title>
<style>
#main {
position: absolute;
bottom: 50px;
left: 200px;
}
#state{
float:right;
width:400px;
}
</style>
<head>
<body>
<div id="main">
<div id="inbox"></div>
</div>
<div id="state"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
var id = null;
function longPolling() {
$.ajax({
url: "update",
data: {"id": id},
type: "POST",
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#state").append("[state: " + textStatus + ", error: " + errorThrown + " ]<br/>");
},
success: function (result, textStatus) {
console.log(result)
msg_data = eval("(" + result + ")");
$("#inbox").append(msg_data.html);
id = msg_data.id;
console.log(msg_data)
$("#message").val("");
$("#state").append("[state: " + textStatus + " ]<br/>");
},
complete: longPolling
});
}
function sendNewMessage() {
$.ajax({
type: "POST",
url: "new",
});
}
$(function(){
longPolling();
})
</script>
</body>
</html>
test.py
from gevent.pywsgi import WSGIServer
from gevent.event import Event
from cgi import escape
import uuid
import urlparse
import string
import random
def get_request_data(field, env):
try:
request_body_size = int(env.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
request_body = env['wsgi.input'].read(request_body_size)
d = urlparse.parse_qs(request_body)
data = d.get(field, [''])[0]
return data
def generate_response_data(response_body, start_response):
response_headers = [('Content-Type', 'text/html'), ('Content-Length', str(len(response_body)))]
start_response('200 OK', response_headers)
return [response_body]
def generate_json_data(msg_list):
msg_dict = {}
msg_dict["html"] = ""
for msg in msg_list:
msg_dict["html"] += "<div>{0}</div>".format(msg["msg"])
msg_dict["id"] = msg_list[-1]["id"]
res = str(msg_dict)
return res
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
file = open('longpooling.html')
chat_html = file.read()
class MessgaeBuffer(object):
def __init__(self):
self.cache = []
self.message_event = Event()
def empty(self):
return len(self.cache) == 0
def application(env, start_response):
env_val = env['PATH_INFO']
if env_val == "/create":
msg_item = {}
msg_item["id"] = str(uuid.uuid4())
msg_item["msg"] = id_generator()
print "create msg %s" % str(msg_item)
msgBuffer.cache.append(msg_item)
msgBuffer.message_event.set()
msgBuffer.message_event.clear()
return generate_response_data("", start_response)
elif env_val == "/update":
lastid = escape(get_request_data("id", env))
if msgBuffer.empty() or msgBuffer.cache[-1]["id"] == lastid:
msgBuffer.message_event.wait()
for index,m in enumerate(msgBuffer.cache):
if m["id"] == lastid:
return generate_response_data(generate_json_data(msgBuffer.cache[index+1:])
, start_response)
return generate_response_data(generate_json_data(msgBuffer.cache), start_response)
else:
return generate_response_data(chat_html, start_response)
msgBuffer = MessgaeBuffer()
WSGIServer(('localhost', 8080), application).serve_forever()
原文链接:http://www.maiziedu.com/wiki/frame/polling/
Gevent的长轮询实现方法详解的更多相关文章
- 实现Comet(服务器推送)的两种方式:长轮询和http流
		
Comet 是一种高级的Ajax技术,实现了服务器向页面实时推送数据的技术,应用场景有体育比赛比分和股票报价等. 实现Comet有两种方式:长轮询与http流 长轮询是短轮询的翻版,短轮询的方式是:页 ...
 - ajax长轮询 (转)
		
javaWeb项目中需要一个实时提醒的功能,也就是某人做了某一操作,可以立即提醒到当前在线的用户 最开始想在用户做了操作后,储存一个状态到数据库中然后用每隔几秒用ajax去请求后台查询数据库来确定是否 ...
 - Python知识之 方法与函数、偏函数、轮询和长轮询、流量削峰、乐观锁与悲观锁
		
方法与函数 函数需要手动传参self.cls,方法自动传,比如对象方法自动传self,类方法自动传cls,而函数相对而言需要手动传,比如静态绑定的函数,self是需要手动传值得,比如我们平常使用的函数 ...
 - gevent中如何实现长轮询
		
浏览网页时,浏览器会传HTTP 请求到服务器,服务器会根据请求将网页的内容传给浏览器,但是在很多的情况下,使用者会需要看到最新的即时性资讯,例如观看股票市场行情,而在以前只能靠着重新载入网页才能获得最 ...
 - 轮询、长轮询和websocket
		
一.轮询 在一些需要进行实时查询的场景下应用比如投票系统: 大家一起在一个页面上投票 在不刷新页面的情况下,实时查看投票结果 1.后端代码 from flask import Flask, rende ...
 - 轮询、长轮询、websock
		
引入 Web端即时通讯技术:即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的.但是在Web中,由于浏览器的限制, ...
 - 你想了解的轮询、长轮询和websocket都在这里了
		
日常生活中,有很多需要数据的实时更新,比如群聊信息的实时更新,还有投票系统的实时刷新等 实现的方式有很多种,比如轮询.长轮询.websocket 轮询 轮询是通过设置页面的刷新频率(设置多长时间自动刷 ...
 - 三周,用长轮询实现Chat并迁移到Azure测试
		
公司的OA从零开始进行开发,继简单的单点登陆.角色与权限.消息中间件之后,轮到在线即时通信的模块需要我独立去完成.这三周除了逛网店见爱*看动漫接兼职,基本上都花在这上面了.简单地说就是用MVC4基于长 ...
 - 用.NET MVC实现长轮询,与jQuery.AJAX即时双向通信
		
两周前用长轮询做了一个Chat,并移植到了Azure,还写了篇博客http://www.cnblogs.com/indream/p/3187540.html,让大家帮忙测试. 首先感谢300位注册用户 ...
 
随机推荐
- volatile关键字解析
			
转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受 ...
 - Servlet基础(下)
			
10.Servlet定义初始化参数必须使用web.xml中的init-param/para-name和 para-value元素;11.ServletConfig对象的getInitParameter ...
 - Android 客户端应用开发的架构
			
本文算是一篇漫谈,谈一谈关于android开发中工程初始化的时候如何在初期我们就能搭建一个好的架构.关于android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的角度,看到整齐 ...
 - Linux 系统裁剪
			
一.前言 Linux操作系统至1991.10.5号诞生以来,就源其开源性和自由性得到了很多技术大牛的青睐,每个Linux爱好者都为其贡献了自己的一份力,不管是在Linux内核还是开源软件等方面,都为 ...
 - IOSView翻转扭矩位移
			
CoreGraphics.h CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI_2);[xxx setTransform: ...
 - IOS文字属性备注
			
// Predefined character attributes for text. If the key is not in the dictionary, then use the defau ...
 - CSocket客户端(TCP)
			
首先是UDP和TCP的区别: UDP是不连接服务器,每次发送数据的时候需要服务器的IP:而TCP是先连接服务器,保持常连接,然后直接发送不需要IP. 下面是TCP客户端: 1.新建项目,TestCSo ...
 - Python3基础 用三个双引号 print输出多行文本
			
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
 - MySql性能优化相关
			
原来使用MySql处理的数据量比较少,小打小闹的,没有关注过性能的问题.最近要处理的数据量飙升,每天至少20W行的新增数据,导致MySql在性能方面已经是差到不可用的地步了,必须要重视MySql的优化 ...
 - Mac功夫——OS X应用技巧
			
看过不少文章说Mac是了不起的先进操作系统,爱折腾的我,经不住诱惑,也玩起了Mac,用惯了Windows,突然换到Mac下还真是十分不习惯,就连复制粘贴这种简单操作也觉得很是别扭. 用过一段时间才感觉 ...