麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

comet在asp.net中的實(shí)現(xiàn)

2019-11-17 01:32:22
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

comet在asp.net中的實(shí)現(xiàn)

2014-05-11 18:02 by xiaozhi_5638, ... 閱讀, ... 評(píng)論, 收藏, 編輯

網(wǎng)上有關(guān)“服務(wù)器推送”的介紹非常多,其中一種實(shí)現(xiàn)方式就是采用comet技術(shù),在瀏覽器與服務(wù)端之間建立一個(gè)http協(xié)議的“長(zhǎng)連接”,所謂“長(zhǎng)連接”,就是指瀏覽器到服務(wù)端的http請(qǐng)求不會(huì)馬上得到服務(wù)端的應(yīng)答,而是當(dāng)滿足一定條件的時(shí)候,服務(wù)器端才“主動(dòng)”將數(shù)據(jù)返回給瀏覽器,這時(shí)候一次http請(qǐng)求才完成,普通http連接與http長(zhǎng)連接見(jiàn)下圖:

圖1

如上圖,左邊為一般http連接,服務(wù)端收到瀏覽器的http請(qǐng)求后會(huì)立即做出應(yīng)答,右邊為http長(zhǎng)連接,服務(wù)端收到瀏覽器的http請(qǐng)求后,如果有數(shù)據(jù)需要返回,則立即返回,否則,服務(wù)端會(huì)“維持住”這個(gè)http請(qǐng)求,也就是說(shuō),服務(wù)端凍結(jié)了該次http請(qǐng)求,直到服務(wù)端有數(shù)據(jù)需要返回給瀏覽器或者超時(shí),服務(wù)端才“解凍”該次http請(qǐng)求,這時(shí)候,一次“瀏覽器->服務(wù)端”的http請(qǐng)求才完整結(jié)束。

“長(zhǎng)連接”的作用很明顯,它能讓服務(wù)端“主動(dòng)”(注意這里的主動(dòng)加了雙引號(hào))將數(shù)據(jù)發(fā)送給瀏覽器,是的,你沒(méi)聽(tīng)錯(cuò),傳統(tǒng)的Web程序只能是瀏覽器主動(dòng)請(qǐng)求服務(wù)端,服務(wù)端再作出應(yīng)答,而現(xiàn)在,服務(wù)端居然可以“主動(dòng)推送”數(shù)據(jù)給瀏覽器了。既然服務(wù)端現(xiàn)在可以“主動(dòng)推送”數(shù)據(jù)給瀏覽器,那么我們可以完成許多之前不能做到的事情,比如“即時(shí)通訊”、“實(shí)時(shí)監(jiān)控”等類似客戶端需要實(shí)時(shí)更新數(shù)據(jù)的應(yīng)用程序了。這里插一句,如果不采用服務(wù)端“主動(dòng)推送”的方式,我們確實(shí)可以按照傳統(tǒng)瀏覽器端使用Ajax主動(dòng)循環(huán)請(qǐng)求服務(wù)端,來(lái)實(shí)現(xiàn)所謂的“實(shí)時(shí)”更新數(shù)據(jù)的效果,比如每秒ajax請(qǐng)求服務(wù)端,來(lái)刷新界面數(shù)據(jù),但是這種方式的缺點(diǎn)可想而知,不管服務(wù)端有沒(méi)有需更新的數(shù)據(jù),瀏覽器都必須不斷地循環(huán)去請(qǐng)求(有關(guān)ajax輪詢的缺點(diǎn)請(qǐng)參考網(wǎng)上其他文章)。

具體實(shí)現(xiàn)comet的關(guān)鍵有以下幾點(diǎn):

1)服務(wù)端不會(huì)立即響應(yīng)瀏覽器的http請(qǐng)求(除非當(dāng)時(shí)有數(shù)據(jù)需要返回給瀏覽器);

2)瀏覽器處理完服務(wù)端返回的數(shù)據(jù)后,要立即重新建立一個(gè)“http長(zhǎng)連接”,供下次使用;

3)瀏覽器在處理服務(wù)端返回的數(shù)據(jù)時(shí)(下一次長(zhǎng)連接建立之前),如果服務(wù)端有新的數(shù)據(jù)需要發(fā)送給瀏覽器,那么服務(wù)端必須將這些新數(shù)據(jù)保存起來(lái),等下次“長(zhǎng)連接”建立后,再一起發(fā)送給瀏覽器;

4)要想服務(wù)端能夠?qū)崟r(shí)地、不斷地“主動(dòng)推送”數(shù)據(jù)到瀏覽器,瀏覽器與服務(wù)端之間必須無(wú)時(shí)無(wú)刻保持一條“http通道”(也就是http長(zhǎng)連接),服務(wù)端能夠借助該通道將數(shù)據(jù)返回給瀏覽器;

5)瀏覽器一接收到服務(wù)端返回的數(shù)據(jù),一次“http長(zhǎng)連接”就結(jié)束了,需要重新建立下一個(gè)。

如果我們以socket編程的角度看“http長(zhǎng)連接”,它會(huì)是這樣的:

圖2

如上圖,每個(gè)browser必須時(shí)刻存在一個(gè)http下行通道(服務(wù)端->瀏覽器,圖中(1)處),這樣任何時(shí)候服務(wù)端都能“主動(dòng)推送”數(shù)據(jù)給browser,同時(shí),每個(gè)瀏覽器均可以發(fā)起其他正常http請(qǐng)求(圖中(2)處),這樣一來(lái),1號(hào)瀏覽器通過(guò)普通http請(qǐng)求發(fā)送數(shù)據(jù)(get/post方式)給服務(wù)端,服務(wù)端就可以立馬將數(shù)據(jù)“推送”給2號(hào)瀏覽器(使用http下行通道),沒(méi)錯(cuò),這不就是socket編程嗎?

asp.net中可以使用“異步編程模型”(APM)簡(jiǎn)單地實(shí)現(xiàn)comet,具體涉及到IHttpAsyncHandler接口以及它的BeginPRocessRequest和EndProcessRequest兩個(gè)方法,當(dāng)我們接收到來(lái)自瀏覽器發(fā)起的“http長(zhǎng)連接”請(qǐng)求時(shí),我們只調(diào)用IHttpAsyncHandler.BeginProcessRequest方法去異步處理,由于我們不立即調(diào)用IHttpAsyncHandler.EndProcessRequest方法,所以這個(gè)http請(qǐng)求不會(huì)立馬結(jié)束(也就是說(shuō),該請(qǐng)求被服務(wù)端凍結(jié)住了),等服務(wù)端有數(shù)據(jù)時(shí),我們?cè)偻ㄟ^(guò)類似Response.Write()方法將數(shù)據(jù)發(fā)送給瀏覽器,同時(shí)調(diào)用IHttpAsyncHandler.EndProcessRequest方法結(jié)束異步處理http請(qǐng)求,這時(shí)候,瀏覽器端會(huì)接收到服務(wù)端“主動(dòng)推送”的數(shù)據(jù),瀏覽器端一次完整的http請(qǐng)求到此時(shí)才結(jié)束,緊接著,瀏覽器端通過(guò)腳本再次發(fā)起一個(gè)“http長(zhǎng)連接”的請(qǐng)求,依次循環(huán)。

文章最后上傳一個(gè)即時(shí)通訊的demo,每個(gè)登錄的用戶都可以發(fā)送消息,在線用戶均能及時(shí)收到服務(wù)端“推送”來(lái)的數(shù)據(jù)(包括上線、下線以及消息內(nèi)容等),由于服務(wù)端發(fā)送的數(shù)據(jù)種類比較多,我簡(jiǎn)單的指定了一個(gè)協(xié)議(protocol),類似如下:

 1 協(xié)議類似socket通訊編程中的協(xié)議(類似): 2 [4bytes]+[16bytes]+[some]+[1byte] 3 消息類型+消息長(zhǎng)度+消息內(nèi)容+驗(yàn)證位 4  5 (Web Server->Browser方向)json格式數(shù)據(jù)包 每個(gè)包類似C++中的結(jié)構(gòu)體: 6  7 有用戶上線: 8 { 9     "type":"login",10     "login_name":"xiaozhi_5638",11     "login_time":"2014-04-15 12:34:19"12 }13 14 有用戶發(fā)送消息:15 {16     "type":"sendmsg",17     "msg":"hello world![emo:23]",18     "send_name":"xiaozhi_5638",19     "send_time":"2014-04-15 12:34:19"20 }21 22 有用戶下線:23 {24     "type":"logout",25     "logout_name":"xiaozhi_5638",26     "logout_time":"2014-04-15 12:34:19"27 }28 29 心跳包:30 {31     "type":"heartbeat",32     "time":"2014-04-15 12:34:19"33 }34 35 自己登錄結(jié)果:36 {37     "type":"login_result",38     "result":"true",   //or false39     "online_users":["xiaozhi_5638","somebody","zhangsan"],  //登錄成功 返回在線用戶40     "time":"2014-04-15 12:34:19"41 }42 43 自己發(fā)送消息結(jié)果44 {45     "type":"sendmsg_result",46     "result":"true",  //or  false47     "msg":"hello world![emo:23]",48     "time":"2014-04-15 12:34:19"49 }50 51 數(shù)據(jù)包集合(上面的都是單個(gè)數(shù)據(jù)包,data_list中包含多個(gè)數(shù)據(jù)包集合) 用于一次性將服務(wù)端緩存的數(shù)據(jù)包傳遞到browser52 {53     "type":"data_list",54     "list":[{"type":"login","login_name":"xiaozhi_5638","login_time":"2014-04-15 12:34:19"},{"type":"sendmsg","msg":"hello world!","send_name":"xiaozhi_5638","send_time":"2014-04-15 12:34:19"}]  //數(shù)組類型 包含多個(gè)數(shù)據(jù)包55 }56 Browser->Web Server方向的數(shù)據(jù) 以普通get/post方式傳遞
View Code

服務(wù)端到瀏覽器端的數(shù)據(jù)均以json格式傳遞,瀏覽器到服務(wù)端采用jquery寫(xiě)好的ajax庫(kù)方式。瀏覽器端的腳本只需要解析服務(wù)端傳遞回來(lái)的json數(shù)據(jù),然后更新界面,緊接著發(fā)起下一個(gè)“http長(zhǎng)連接”請(qǐng)求。js腳本發(fā)起http長(zhǎng)連接代碼如下:

 1 function Open_Http_Channel()  //開(kāi)啟一個(gè)http通道(http長(zhǎng)連接) 2 { 3     $.ajax( 4     { 5         url:"chat_aspx.ashx",  //action處理頁(yè)面 6         type:"post",  //數(shù)據(jù)傳遞方式 7         data:{"requestType":"a_long_connection","id":$("#input_user_name").val()},   //上傳參數(shù) 8         dataType:"json",  //返回?cái)?shù)據(jù)類型 9         success:function(data)  //解析返回的json包10         {11             //接收web server端返回的數(shù)據(jù)  開(kāi)始解析數(shù)據(jù) 參見(jiàn)protocol.txt12             if(data.type == "login")  //有人上線13             {14                 ShowLogin(data);  //顯示登錄信息15             }16             if(data.type == "sendmsg")  //有人發(fā)送消息17             {18                 ShowMsg(data.msg,data.send_time,data.send_name);  //顯示消息19             }20             if(data.type == "logout")  //有人下線21             {22                 Logout(data);23             }24             if(data.type == "data_list")  //數(shù)據(jù)包集合25             {26                 for(i in data.list)  //遍歷數(shù)據(jù)包集合27                 {28                     if(data.list[i].type == "login")29                     {30                         ShowLogin(data.list[i]);   //顯示登錄信息31                     }32                     if(data.list[i].type == "sendmsg")33                     {34                         ShowMsg(data.list[i].msg,data.list[i].send_time,data.list[i].send_name);  //顯示消息35                     }36                     if(data.list[i].type == "logout")  //下線37                     {38                         Logout(data.list[i]);39                     }40                     //...41                 }42             }43             //...44             //...45             //...定義的其他協(xié)議  在此處解析46             Open_Http_Channel();  //馬上開(kāi)啟第二次http通道47         },48         error:function(xhr,info,obj)49         {50             Open_Http_Channel();  //馬上開(kāi)啟第二次http通道              51         }52     });53 }
View Code

其他具體詳細(xì)的說(shuō)明參見(jiàn)源代碼。效果圖一張圖3(gif表情沒(méi)有解析替換,直接顯示的文本)

圖3

源碼地址:http://files.VEVb.com/xiaozhi_5638/comet_in_aspnet.rar vs2008

用到了jquery以及跟它相關(guān)的幾個(gè)界面庫(kù)。注意不要在同一個(gè)瀏覽器上登錄太多用戶,因?yàn)闉g覽器會(huì)為每個(gè)用戶維持一個(gè)http連接,而瀏覽器對(duì)http請(qǐng)求數(shù)量有限制(筆者用的Chrome上限為6個(gè)),超過(guò)上限的話,之后所有http請(qǐng)求都會(huì)被阻塞。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本网站一区二区三区 | 国产乱色精品成人免费视频 | 国产精品久久久久久久久久东京 | 毛片大全 | 日韩在线毛片 | 黄色的视频在线观看 | 最近免费观看高清韩国日本大全 | 免费午夜视频 | 羞羞视频免费网站 | 在线天堂中文在线资源网 | 国产一区二区视频精品 | 欧美伦理一区二区 | a视频网站 | 亚洲性综合网 | 国产99久久久久久免费看农村 | 天天躁狠狠躁夜躁2020挡不住 | 蜜桃一本色道久久综合亚洲精品冫 | 黄色影院在线看 | 俄罗斯16一20sex牲色另类 | 久久成人国产精品入口 | 日韩在线毛片 | 国产精品久久久久影院老司 | 久久激情小视频 | 国产一级不卡毛片 | 婷婷久久青草热一区二区 | 中文字幕一区二区三区四区 | 男女生羞羞视频网站在线观看 | 操你啦免费视频 | 中文字幕在线观看视频一区 | 欧美一级片免费在线观看 | 亚洲人成综合第一网 | 久久人人97超碰国产公开结果 | 毛片在线视频观看 | 日韩黄色一区 | qyl在线视频精品免费观看 | 国产jjizz一区二区三区视频 | av在线免费观看不卡 | 天天色综合2 | 久久久久久久久久久亚洲 | 中文字幕在线播放不卡 | 性盈盈盈影院 |