在网上搜了搜,没有发现C#实现http长连接的开源项目,估计是实现起来太简单了吧。自己写一个,不是项目中使用,纯粹测试一下。
创新互联公司专注于郧西网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供郧西营销型网站建设,郧西网站制作、郧西网页设计、郧西网站官网定制、小程序设计服务,打造郧西网络公司原创品牌,更为您提供郧西网站排名全网营销落地服务。1、原理
所谓长连接,是指客户端以http协议连接到服务器,区别于一般的短连接,服务器不会立即返回数据,而是保持住这个连接,等到有数据时才返回。说起来简单,但却不能使用Sleep或者信号量的方式保持住连接,因为这么做会长时间占用线程,客户端多时很快会占满ASP.Net的线程池。
ASP.Net提供了IHttpAsyncHandler接口,允许开发者以异步方式处理http请求。示意图如下:
Http请求到达服务器后,被BeginProce***equest方法处理,它个方法要生成一个IAsyncResult对象,并将其保存到其它地方,之后返回。此时连接将保持住,但ASP.Net已经可以空出资源去处理下一个请求了。直到程序的业务逻辑触发IAsyncResult对象的Callback,IHttpAsyncHandler对象的EndProce***equest方法才被调用,此时可以做输出,之后这个http请求才真正结束。
2、IHttpAsyncHandler实现
using System; using System.Web; namespace Comet { public class CometAsyncHandler : IHttpAsyncHandler { ////// 请求到达时的处理方法 /// public IAsyncResult BeginProce***equest(HttpContext context, AsyncCallback callback, object extraData) { //通过context可以取请求附加的数据,略 //... //之后生成IAsyncResult对象,callback比较重要,调用这个回调,EndProce***equest才被触发 var result = new CometResult(context, callback, extraData); //在返回之前把刚生成的IAsyncResult对象保存起来,略 //... return result; } ////// 请求结束时的处理方法 /// public void EndProce***equest(IAsyncResult asyncResult) { //得到对应的IAsyncResult对象 var result = asyncResult as CometResult; //后续处理,如输出内容等,略 //... } public bool IsReusable { get { return false; } } public void Proce***equest(HttpContext context) { throw new NotImplementedException(); } } }
3、IAsyncResult实现
using System; using System.Web; using System.Threading; namespace Comet { public class CometResult : IAsyncResult { #region 实现IAsyncResult接口 public object AsyncState { get; private set; } public WaitHandle AsyncWaitHandle { get; private set; } public bool CompletedSynchronously { get; private set; } public bool IsCompleted { get; private set; } #endregion public AsyncCallback Callback { get; private set; } public HttpContext Context { get; private set; } public object ExtraData { get; private set; } public CometResult(HttpContext context, AsyncCallback callback, object extraData) { this.Context = context; this.Callback = callback; this.ExtraData = extraData; } public Call() { if(this.Callback != null) this.Callback(this); } } }
4、调用
找到对应的IAsyncResult对象,调用其Call方法即可。
5、配置文件
在
考虑到兼容IIS7,还要在
6、针对MVC的特殊处理
增加HttpHandler会受mvc影响,需要在RegisterRoutes方法里加忽略:
//忽略Data.aspx routes.IgnoreRoute("Data.aspx/{*pathInfo}");
搞定收工,请求Data.aspx时,连接会被保持住,直到通过另一个页面调用IAsyncResult对象的Call方法,当前连接才会返回。
简单测试了一下,保持3000个连接很轻松,并且都能快速响应,达到了预期。由于.net有默认大并发连接数的限制,客户端如果开多个连接,需要把 ServicePointManager.DefaultConnectionLimit 调大一些。另外开到1300多个连接的时候就报OutOfMemoryException了,所以要多用几台客户端测。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网页标题:ASP.Net实现Http长连接(Comet)-创新互联
网页网址:http://lswzjz.com/article/dsoehj.html