亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Asp.Net實現Http長連接推送

2019-11-17 01:46:00
字體:
來源:轉載
供稿:網友

asp.net實現Http長連接推送

話說最新幫一個朋友搞智能家居方面的東西,做一個云平臺。主要作用手機在局域網外環境時對手機客戶端和智能網關中命令的互相轉發。

目前已經有了一個穩定的Socket版本,但是考慮到以后的擴展和性能指標要改成Http長連接形式,這確實是一個很逗逼的方案。

下面普及一下Http長連接的概念,所謂的Http長連接其實不是指像Socket那樣的建立一個連接client端和server端來回傳遞數據。Http長連接指的是客戶端發送給服務器端的Http請求不會馬上得到服務器的應答,而是當滿足一定條件時服務器才“主動”將數據返回給客戶端,這時一次Http請求才算結束。實際應用中為客戶端在結束了一個長連接后往往要再次建立一個長連接,也就是客戶端到服務器端總是維持一個打開的下行Http通道。

搞過Socket的同學都知道,Socket通訊中除了有自己的協議以外還要有心跳的命令,以此來保證客戶端和服務器端連接的狀態。這些本文都不去深究,主要還是說長連接的這個小框架。

代碼是我們最好的伙伴,下面我們結合代碼說說這個簡單的東西。

Asp.Net4.0中加入了很多異步特性,其中IHttpAsyncHandler配合IAsyncResult可以很好的解決本文的需求。首先我們定義一個類實現IAsyncResult這個接口

using System;using System.Collections.Generic;using System.Linq;using System.Web;using log4net;namespace SM.BIZKeepAliveHttp{    /// <summary>    /// 一個異步會話,會話會被臨時緩存    /// </summary>    public class HKAsyncRequest : IAsyncResult    {        PRivate static readonly ILog logger = LogManager.GetLogger(typeof(HKAsyncRequest));        public HKAsyncRequest(HttpContext context, AsyncCallback cb, object extraData)        {            this.Context = context;            this.CallBack = cb;            this.ExtraData = extraData;        }        public HttpContext Context        {            get;            set;        }        public object ExtraData        {            get;            set;        }        public AsyncCallback CallBack        {            get;            set;        }        public bool IsCompleted        {            get;            set;        }        public object AsyncState        {            get;            set;        }        public System.Threading.WaitHandle AsyncWaitHandle        {            get;            set;        }        public bool CompletedSynchronously        {            get { return false; }        }        public void Send(string response) {            if (String.IsNullOrEmpty(response))                return;            try            {                this.Context.Response.ContentType = "text/plain";                this.Context.Response.Write(response);                if (this.CallBack != null)                {                    this.CallBack(this);                 }            }            catch (Exception ex)            {                logger.Error("輸出到客戶端發生錯誤:" + ex.Message);            }            finally             {                IsCompleted = true;             }        }        public void Send(byte[] b,int offset,int length){            string str = Func.ByteArrayToHexString(b);            this.Send(str);        }    }}

這個類沒有什么難的,主要是保存外部傳進來的HttpContext、AsyncCallBack和ExtraData,HttpContext用來向Response中寫回應,AsyncCallBack用來結束當前Http長連接請求,ExtraData自己該干什么干什么我沒有用它。這里需要注意的是這個類中的CompletedSynchronously屬性要返回false,不然客戶端收不到數據。而且各個屬性也別隨便返回null,不然在寫入Response時會報空指針的錯誤。

下面我們看看另一個接口的實現。在項目中新建一個一般處理程序(.ashx)文件。實現IAsyncHandler接口:

using System;using System.Collections.Generic;using System.Linq;using System.Web;using log4net;using Newtonsoft.Json.Linq;namespace SM.BIZKeepAliveHttp{    public class Data : IHttpAsyncHandler    {        public static readonly string DATAFIELD = "data";        private static readonly ILog logger = LogManager.GetLogger(typeof(Data));        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)        {            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);            string value = context.Request.Params.Get(DATAFIELD);            //這里傳過來的是sessionId,不是數據,數據不做重復Parse            //用sessionId去緩存中找對應的會話,并填充異步AsyncResult            HKAsyncRequest result = new HKAsyncRequest(context, cb, extraData);            string error = null;            if (String.IsNullOrEmpty(value))            {                error = "500 SessionId is null";                context.Response.StatusCode = 500;                logger.Error(error);                result.Send(error);                return result;            }            List<AliveClient> acs = AsyncManager.Sessions.FindAll(x => x.SessionId.Equals(value));            if (acs == null || acs.Count == 0)            {                error = "404 SessionId:" + value + " has no connection.";                context.Response.StatusCode = 404;                logger.Debug(error);                result.Send(error);                return result;            }            AliveClient ac = acs.First();            ac.Result = result;            //執行命令            CommondFactory.ExecuteCommond(ac);            return result;        }        public void EndProcessRequest(IAsyncResult result)        {        }        public void ProcessRequest(HttpContext context)        {        }        public bool IsReusable        {            get            {                return false;            }        }    }}

這個類中主要實現的方法只有一個,那就是BeginProcessRequest,其他方法不用寫任何代碼。這個方法主要作用是建立一個IAsyncResult實例后保存起來,便于以后服務器端有了數據或是滿足了特定情況把數據返回給客戶端。所以我在代碼里面建立了一個靜態List的緩存保存這些IAsyncResult實現。當然這就是Asp.Net實現Http長連接的核心所在了。 其它的就不多說了,大家可以看源代碼,看代碼時大家會發現我實際建立了兩個.ashx文件,這和我這個項目的邏輯有關,因為協議規定客戶端發送一條數據后服務器端馬上要做出回應,所以我用一個傳統的ashx作回應,回應前這個傳統的ashx(connection.ashx)先分析數據把分析后的數據模型保存起來,同時給客戶端一個SessionId。客戶端收到回應后用這個SessionId發起長連接請求,服務器端就不再重復分析數據了,而是將之前的數據從緩存中取出使用,為了調試方便我把這個SessionId寫死了。同時我用Quartz.Net建立了兩個任務,一個CleanJob.cs實際是作為清理任務,定時清理掉緩存中的無效或已完成請求5分鐘跑一次。還有一個任務是HeartJob.cs主要是用來模擬服務器端推送的邏輯,30秒跑一次。

用到Quartz.Net是因為我個人認為在Asp.net中直接啟動BackgroundWorker的方式不是很好,還是調度引擎的線程模型更可靠。具體啟動調度引擎的代碼在Global.asax里面。

附件中是我剝離出來的代碼,刪除了業務部分只做測試用。測試界面為index.aspx,在文本框中寫點東西點提交,先收到服務器的回應后每個30秒收到服務器的回應彈出alert窗口。這里要提的就是客戶端js代碼在收到一個長連接反饋后馬上又建立一個長連接,這是關鍵所在。

源代碼


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲专区中文字幕| 国产午夜精品一区理论片飘花| 久久精品电影网站| 国产精品久久久久久中文字| 992tv在线成人免费观看| 欧美三级xxx| 欧美日韩中文字幕日韩欧美| 欧美在线观看网站| 国产一区二区三区免费视频| 日本欧美精品在线| 日韩精品视频在线观看免费| 国产精品久久久久久久久久久久久久| 久久久久久久久久av| 日韩国产欧美精品一区二区三区| 久久精品91久久香蕉加勒比| 亚洲欧美在线x视频| 日韩免费观看高清| 亚洲色图50p| 亚洲女同性videos| 国产精品福利无圣光在线一区| 久久久免费高清电视剧观看| 久久视频免费观看| 丁香五六月婷婷久久激情| 亚洲综合在线中文字幕| 欧美专区在线观看| 欧美激情第99页| 国产一区二区三区视频免费| 欧美成人一二三| 欧美丰满少妇xxxxx| 欧美日韩中文字幕| 日韩精品中文字幕在线播放| www.亚洲成人| 亚洲jizzjizz日本少妇| 色综合久久88色综合天天看泰| 久久久久久久久久国产精品| 国产精品伦子伦免费视频| 久久久精品影院| 国产精品三级久久久久久电影| 欧美日韩国产一区在线| 日韩欧美视频一区二区三区| 国产亚洲一区二区在线| 国产亚洲激情视频在线| 国产精品免费电影| 亚洲国产中文字幕在线观看| 97久久精品人人澡人人爽缅北| 日本一区二区在线免费播放| 日韩av网站大全| 亚洲午夜精品久久久久久性色| 国内精品国产三级国产在线专| 性色av一区二区咪爱| 国产精品igao视频| 国产精品ⅴa在线观看h| 成人av在线亚洲| 久久天天躁狠狠躁夜夜躁2014| 亚洲色图五月天| 欧美高清第一页| 国产欧美中文字幕| 国产69久久精品成人看| 性色av一区二区三区红粉影视| 国产精品91免费在线| 国产一区二区三区在线观看网站| 国产精品久久久久久av下载红粉| 精品国产一区av| 伊人成人开心激情综合网| 日韩欧美aⅴ综合网站发布| 亚洲欧美国产一本综合首页| 午夜美女久久久久爽久久| 国产精品免费视频xxxx| 久久久成人精品| 日韩成人av网| 亚洲免费av网址| 国产精品综合网站| 亚洲天堂免费视频| 久久亚洲精品小早川怜子66| 黄网动漫久久久| 亚洲a成v人在线观看| 欧美性在线视频| 日韩精品亚洲视频| 中文字幕亚洲综合久久筱田步美| 精品久久久久久电影| 国产欧美va欧美va香蕉在线| 国产精品∨欧美精品v日韩精品| 亚洲激情视频网站| 久久久之久亚州精品露出| 国产午夜精品麻豆| 久久精品99国产精品酒店日本| 国产精品视频一区二区高潮| 日韩精品一区二区三区第95| 亚洲日本成人女熟在线观看| 欧美视频一区二区三区…| 久久精视频免费在线久久完整在线看| 精品国产一区二区三区久久狼黑人| 国产精品永久免费视频| 欧美日韩亚洲一区二| 欧美色道久久88综合亚洲精品| 91精品国产乱码久久久久久蜜臀| 久久久久国产一区二区三区| 国产三级精品网站| 欧美日韩国产限制| 国产精品99久久久久久久久久久久| 97在线视频免费观看| www.日韩不卡电影av| 欧美电影在线观看网站| 2019国产精品自在线拍国产不卡| 亚洲aaaaaa| 色婷婷**av毛片一区| 色老头一区二区三区在线观看| 日韩www在线| 成人黄色午夜影院| 欧美日韩精品在线播放| 中文字幕精品在线视频| 97精品免费视频| 久久久噜噜噜久久中文字免| 国产在线一区二区三区| 日本最新高清不卡中文字幕| 另类少妇人与禽zozz0性伦| 青青久久av北条麻妃海外网| 91免费看片在线| 国产精品一区二区久久久| 性夜试看影院91社区| 91丝袜美腿美女视频网站| 精品伊人久久97| 亚洲裸体xxxx| 亚洲无限av看| 91精品国产91久久久久福利| 国产精品日韩在线一区| 国产精品99久久久久久久久久久久| 最新国产精品亚洲| 国语自产在线不卡| 国产亚洲一区二区在线| 欧美一级在线播放| 在线亚洲男人天堂| 亚洲网在线观看| 日韩网站在线观看| 欧美猛少妇色xxxxx| 亚洲毛片在线观看| 欧美大片在线影院| 国产精品久久久久久一区二区| 国产精品18久久久久久首页狼| 在线视频亚洲欧美| 91成品人片a无限观看| 日韩成人在线网站| 久久精品福利视频| 精品亚洲一区二区三区在线播放| 大伊人狠狠躁夜夜躁av一区| 青青草一区二区| 国产精品久久久av| 国产激情久久久久| 国产精品99导航| 国产精品成人久久久久| 91精品国产自产在线| 日本最新高清不卡中文字幕| 欧美综合第一页| 国产精品美乳在线观看| 亚洲精选在线观看| 久久这里只有精品视频首页| 国产综合在线观看视频| 国产99视频精品免视看7| 亚洲国产精品人久久电影| 中文字幕欧美精品在线| 亚洲欧洲成视频免费观看| 中文字幕一精品亚洲无线一区| 欧美日韩一二三四五区| 国产精品pans私拍|