comet(http 请求长连接) 之 ajax 长查询 简单实现。


======================================================
注:本文源代码点此下载
======================================================

comet(http 请求长连接) 之 ajax 长查询 简单实现。

这几天看到几篇关于http 长连接的文章,之前做过一个简单webim 采用ajax定时查询,效率一般,请求一多 iis 日志每天大概有80m左右。在线人数在40人左右(基本和挂qq一样)。

今天特意研究了一下http 的长连接。有了一点点成果。现放出来大家一起讨论一下。

不清楚长连接请点这里

1.客户端请求

script type="text/javascript">

var httprequest;

function createxmlhttprequest()

{

if(window.xmlhttprequest)

{

httprequest=new xmlhttprequest();

}

else if(window.activexobject)

{

httprequest=new activexobject("microst.xmlhttp");

}

}

function send()

{

document.getelementbyid("test").innerhtml="等待返回信息";

createxmlhttprequest();

if(httprequest!=null)

{

httprequest.onreadystatechange=showmessage;

httprequest.open("get","handler.ashx?name="+escape("leon")+"&m"+math.random());

httprequest.send();

}

}

function showmessage()

{

if(httprequest.readystate==4&&httprequest.status==200)

{

if(httprequest.responsetext.length>0)

{

alert(httprequest.responsetext);//收到信息

//如果有信息返回 重新发送请求 递归

send();

}

}

}

/script>

2.服务的如何hold请求

code

public class handler : ihttphandler

{

private bool ok = true;

public void processrequest(httpcontext context)

{

ok = true;

while (ok)//超时设置ok为false即可

{

//循环检查是否有信息存在

check();

//防止循环太频繁

system.threading.thread.sleep(1000);

}

}

private void check()

{

listmessage> list = new listmessage>();//信息列表

string str = "";

lock (im.mlist)

{

if (im.mlist.count > 0)

{

foreach (message m in im.mlist)

{

if (m.username == httpcontext.current.request["name"].tostring())

{

list.add(m);

str = m.messagecontent;

break;

}

}

if (list.count > 0)

{

foreach (message m in list)

{

im.mlist.remove(m);

}

}

//收到信息 循环结束

ok = false;

if (list.count > 0)

{

//推信息

httpcontext.current.response.write("收到信息:" + str);

}

}

}

}

public bool isreusable

{

get

{

return false;

}

}

}

============================================================

示例代码:fck.rar

生命是一个过程,可悲的是这个过程不能够重来。

绿色通道:好文要顶关注我收藏该文与我联系

posted on 2009-10-10 14:08 leon yang 阅读(4753) 评论(39)编辑 收藏

feedback:

1793746

#1楼

2009-10-10 14:36 | 沛沛

生命是一个过程,可悲的是这个过程不能够重来。

可喜的是他也不需要重来

回复 引用 查看

#2楼

2009-10-10 14:42 | yjj

引用沛沛:

生命是一个过程,可悲的是这个过程不能够重来。

可喜的是他也不需要重来

恭喜你

回复 引用 查看

#3楼

2009-10-10 14:52 | rosanshao

朋友,你的代码不是http长连接吧,是http多连接

http长连接的关键是在服务端

回复 引用 查看

#4楼

2009-10-10 15:06 | careyson

利用httphandler来"hold"貌似是一个很不错的方法.

ps:"im"这个变量是从哪跑出来的?

回复 引用 查看

#5楼

2009-10-10 16:35 | zork

用异步httphandler吧,性能有质的飞跃。

回复 引用 查看

#6楼[楼主]

2009-10-10 16:42 | leon yang

@rosanshao

请仔细看完服务端代码。或者下载示例代码自己测试。

注意这里

public void processrequest(httpcontext context)

{

ok = true;

while (ok)//超时设置ok为false即可

{

//循环检查是否有信息存在

check();

//防止循环太频繁

system.threading.thread.sleep(1000);

}

}

//while循环代码不停止 当前request 是不会结束的。

也就是说请求得不到服务器的response 所以连接时一直保持的 除非超时。

回复 引用 查看

#7楼[楼主]

2009-10-10 16:44 | leon yang

@careyson

im这个在示例代码里面的。

回复 引用 查看

#8楼

2009-10-10 16:48 | coolin

引用rosanshao:

朋友,你的代码不是http长连接吧,是http多连接

http长连接的关键是在服务端

同意,我感觉这也不叫长连接,只是通过循环去检查有无信息,好像把前台通过ajax的轮询搬到了后台。

回复 引用 查看

#9楼[楼主]

2009-10-10 16:54 | leon yang

@coolin

请仔细看这片介绍。

http://www.cnblogs.com/happyday56/archive/2009/06/10/1500427.html

回复 引用 查看

#10楼

2009-10-10 20:00 | q.lee.lulu

response.write后并没有flush啊,内容不会写到客户端吧。。。

回复 引用 查看

#11楼[楼主]

2009-10-10 20:10 | leon yang

@q.lee.lulu

为什么write后面要response.flush??

write的时候 客户端与服务端 任然是保持连接的 客户端为什么会收不到呢?

请自己测试示例代码。

回复 引用 查看

#12楼[楼主]

2009-10-10 20:15 | leon yang

普通的请求 服务端可能1秒之内就处理完了 客户端马上收到response信息,连接当然就断开了。

这里的长连接就是要拖延服务端的response

加长服务端处理的时间 客户端得不到服务端的response 当然只能一直与服务端保持连接。

回复 引用 查看

#13楼

2009-10-10 20:35 | q.lee.lulu

厄~~~看到ok=false了

你这个根本不是长连接,在服务器收到信息后连接就完成了。。。

回复 引用 查看

#14楼

2009-10-10 20:42 | jeffrey zhao

不异步是不行滴。

回复 引用 查看

#15楼

2009-10-10 21:11 | omeweb

不错,我已经根据这个做了一个分布式的im出来了,多交流

回复 引用 查看

#16楼[楼主]

2009-10-10 21:56 | leon yang

@q.lee.lulu

基于长轮询的服务器推模型

500) this.width=500;">

回复 引用 查看

#17楼[楼主]

2009-10-10 22:06 | leon yang

@omeweb

恩 一起交流。

回复 引用 查看

#18楼

2009-10-10 22:24 | q.lee.lulu

@leon yang

你贴的图上面写着的是长轮询,在一次会话过程中也是要不停的发送新的请求的。

长连接我的理解是发起会话,一直到他退出会话,这个连接都是一直保持连接状态的。

回复 引用 查看

#19楼[楼主]

2009-10-10 22:42 | leon yang

引用q.lee.lulu:

@leon yang

你贴的图上面写着的是长轮询,在一次会话过程中也是要不停的发送新的请求的。

长连接我的理解是发起会话,一直到他退出会话,这个连接都是一直保持连接状态的。

这样子不是有悖http协议吗?这种超长的连接也是不适合互联网的吧。这里的长连接是为了减少客户端得频繁request.

回复 引用 查看

#20楼

2009-10-11 00:18 | canbeing

好像不是一个长连接,

服务器会不会超时啊?

回复 引用 查看

#21楼

2009-10-11 01:16 | 奇军

connection:keep-live

改造一下,不行?

或者藏个flash,tcp

回复 引用 查看

#22楼

2009-10-11 01:44 |d

while (ok) 改为 while (response.isclientconnected)

好点

回复 引用 查看

#23楼

2009-10-11 03:04 | erer[未注册用户]

iis的连接数是有限的 这样长时间占用连接好吗?

回复 引用

#24楼

2009-10-11 09:49 | 在别处

楼主的意思长连接就是长时间的连着服务器,等到信息读取完毕然后断开?

回复 引用 查看

#25楼

2009-10-11 10:06 | 毛毛鱼[未注册用户]

我的毕业设计做的就是这个东西,核心代码和楼主的差不多。建议楼主可以用些事件代理,会更加方便。

回复 引用

#26楼[楼主]

2009-10-11 11:41 | leon yang

@在别处

请看这篇关于comet的介绍

http://www.cnblogs.com/happyday56/archive/2009/06/10/1500427.html

回复 引用 查看

#27楼[楼主]

2009-10-11 11:43 | leon yang

@毛毛鱼

呵呵,我只是做了一个简单示例 还没有深入研究 暂时记录下来 以后有时间再深入研究。

回复 引用 查看

#28楼[楼主]

2009-10-11 11:46 | leon yang

@erer

我想这个应该不需要去担心吧。

gmail+gtalk 都有应用。

回复 引用 查看

#29楼

2009-10-11 11:57 | 毛毛鱼[未注册用户]

@leon yang

在codeplex有个comet的.net实现,你可以下载下来研究下。

回复 引用

#30楼

2009-10-11 13:10 | 在别处

引用leon yang:

@在别处

请看这篇关于comet的介绍

http://www.cnblogs.com/happyday56/archive/2009/06/10/1500427.html

此内容很久以前就见过,只是觉得您现在的这个while+sleep的设计似乎不那么合理,不实时估计效率也不很高。

回复 引用 查看

#31楼

2009-10-11 13:41 | 毛毛鱼[未注册用户]

@在别处

可以使用多个线程,在线程中while+sleep保证实时和效率。

回复 引用

#32楼

2009-10-11 22:09 | 黑子范

做个记号

回复 引用 查看

#33楼

2009-10-12 09:10 | rocklau

被虐了.

回复 引用 查看

#34楼

2009-10-12 09:29 | normren

引用leon yang:

@q.lee.lulu

为什么write后面要response.flush??

write的时候 客户端与服务端 任然是保持连接的 客户端为什么会收不到呢?

请自己测试示例代码。

response.flush可以将缓冲区内容立即送出。

回复 引用 查看

#35楼[楼主]

2009-10-12 09:39 | leon yang

@normren

不适合ajax方式。ajax请求客户端收不到的(ie中)。你可以自己测试下。

---------------------------------------------

mozilla firefox 提供了对 streaming ajax 的支持, 即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。ie 在 readystate 为 3 时,不能读取服务器返回的数据,目前 ie 不支持基于 streaming ajax。

----------------------------------------------

回复 引用 查看

#36楼

2009-11-13 20:14 | gotolnc

不支持ie的确头大啊,这样应用可能就小很多了,有的新的解决方案吗。

回复 引用 查看

#37楼

2009-11-18 01:52 | nikeaa[未注册用户]

http://www.cnblogs.com/images/cnblogs_com/leon_yang/leon1.gif

这个框架能分享一份吗?

zhdqcn@gmail.com

多谢

回复 引用

#38楼[楼主]

2009-11-18 08:35 | leon yang

@nikeaa

不好意思。暂时还没有做出一个完整的框架。

回复 引用 查看

#39楼

2010-04-04 12:15 | mr.realm

谢了我用这个方法已经做了个跟qq差不多的im了差多对多聊天弄弄就搞定了

回复 引用 查看

注册用户登录后才能发表评论,请 登录 或 注册,返回博客园首页

首页博问闪存新闻园子招聘知识库

最新it新闻:

·android平台12月广告浏览份额51.6% 超越ios

·测试版ios源代码显示ipad 3或将支持siri

·斯蒂芬·霍金的新电脑

·京东商城2.95亿竞得北京商业地一块

·美报业巨头合作facebook谷歌 传媒重视网络网络

» 更多新闻...

最新知识库文章:

·javascript 面向对象编程

·持续集成之“everything is code”

·持续集成之“软件自我识别”

·持续集成之戏说check-in dance

·什么是闭包。
       我的理解

» 更多知识库文章...

china-pub 2011秋季教材巡展

china-pub 计算机绝版图书按需印刷服务


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值