内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

使用GoHijack和jQuery輕松實(shí)現(xiàn)異步推送服務(wù)

首先要說(shuō)明的是,這里實(shí)現(xiàn)的異步推送服務(wù)采用的是Long Polling方式,并不是Comet。

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供淮安區(qū)網(wǎng)站建設(shè)、淮安區(qū)做網(wǎng)站、淮安區(qū)網(wǎng)站設(shè)計(jì)、淮安區(qū)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、淮安區(qū)企業(yè)網(wǎng)站模板建站服務(wù),10多年淮安區(qū)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

如果想用Comet來(lái)實(shí)現(xiàn)的話,可以參考這個(gè)開(kāi)源項(xiàng)目:http://cometd.org/。不過(guò)其中的服務(wù)端實(shí)現(xiàn)只有Java版和Python版。如果要用Go來(lái)做后端的話需要自己實(shí)現(xiàn)Bayeux協(xié)議。

關(guān)于異步推送服務(wù)的解決方案的資料有很多,在這里就不在贅述了。當(dāng)然,當(dāng)前最先進(jìn)的兩個(gè)方案就是Long Polling和Comet。

1. 預(yù)備知識(shí)

1.1 Go語(yǔ)言

關(guān)于Go語(yǔ)言,其實(shí)要說(shuō)的很多。但是為了不跑題,請(qǐng)大家移步到這里:http://code.google.com/p/golang-china/。另外,Go語(yǔ)言的官網(wǎng)地址是:http://golang.org/。

1.2 Hijack

Hijack其實(shí)是一個(gè)單詞,雖然有很多人把它和電影《泰坦尼克號(hào)》中Rose的召喚聯(lián)系到一起。Hijack被譯為劫持,在“處理HTTP請(qǐng)求”的這個(gè)上下文中,就意味著可以讓我們“劫持”(或者說(shuō)“保持”)HTTP請(qǐng)求鏈接,做一些其他操作(比如根據(jù)需要修改HTTP響應(yīng)的內(nèi)容),然后再在之后的某個(gè)時(shí)間將響應(yīng)“推送”回去。說(shuō)到這,我想這就與Long Polling的運(yùn)作方式很相似了。

Go語(yǔ)言的Hijack接口非常簡(jiǎn)單,我們?cè)诠俜降奈臋n站點(diǎn)上可以找到說(shuō)明:http://godoc.org/net/http#Hijacker。本文中的核心代碼也是來(lái)自于此文檔。

1.3 jQuery

jQuery作為當(dāng)今最流行的Javascript開(kāi)發(fā)框架,我想基本上每一個(gè)做過(guò)Web開(kāi)發(fā)的人都會(huì)知道,所以在這里我就不多說(shuō)了。如果你不知道,可以看這里:http://jquery.com/。

2. 實(shí)戰(zhàn)

2.1 需求

在本案例中,我需要做一個(gè)能實(shí)時(shí)查看當(dāng)前授權(quán)碼的頁(yè)面,而且我不想手動(dòng)刷新頁(yè)面。另外,我還想記錄一下從頁(yè)面打開(kāi)到當(dāng)前時(shí)刻授權(quán)碼改變過(guò)多少次。因?yàn)槭跈?quán)碼在被使用后會(huì)自動(dòng)變更一次,所以授權(quán)的變更次數(shù)就等于使用授權(quán)碼服務(wù)的人數(shù)。

2.2 編寫服務(wù)端代碼

之前說(shuō)了,我們使用Go語(yǔ)言來(lái)編寫后端代碼。我們要使用Go語(yǔ)言的官方http庫(kù)。

其中,我們需要用http.HandleFunc來(lái)注冊(cè)針對(duì)某個(gè)url的請(qǐng)求處理器。如下:

  1. http.HandleFunc("/auth_code", getAuthCodeForAdmin) //向http服務(wù)器注冊(cè)一個(gè)對(duì)指定url進(jìn)行處理的函數(shù)。 

在函數(shù)getAuthCodeForAdmin的簽名中,有兩個(gè)參數(shù)——http.Request對(duì)象指針和http.ResponseWriter對(duì)象。http.Request對(duì)象指針用來(lái)獲取請(qǐng)求信息,http.ResponseWriter對(duì)象用來(lái)寫入響應(yīng)。

如果要使用Go的Hijack方式來(lái)處理HTTP請(qǐng)求,就需要先import其官方的http包:

  1. import ( "net/http" ) 

之后,我們?cè)谔幚砗瘮?shù)getAuthCodeForAdmin中先將http.ResponseWriter對(duì)象顯式轉(zhuǎn)換為http.Hijacker接口:

  1. hj, ok := w.(http.Hijacker) 

返回值中賦給“ok”變量的值代表轉(zhuǎn)換是否成功,如果不成功就說(shuō)明http.ResponseWriter對(duì)象未實(shí)現(xiàn)http.Hijacker接口。

如果轉(zhuǎn)換成功,我們就可以調(diào)用http.Hijacker接口的Hijack方法來(lái)獲取連接對(duì)象及其讀寫緩存對(duì)象了:

  1. conn, bufrw, err := hj.Hijack() 

返回值中,“conn”代表連接對(duì)象,“bufrw”代表該連接的讀寫緩存對(duì)象。

如果返回值“err”等于nil就說(shuō)明獲取成功,我就可以繼續(xù)下面的事情了。但首先需要在函數(shù)推出前關(guān)閉連接,不論函數(shù)是否執(zhí)行成功以及是否有錯(cuò)誤發(fā)生:

  1. defer conn.Close() 

使用defer關(guān)鍵字意味著,讓程序執(zhí)行流程退出該函數(shù)前先執(zhí)行緊隨其后的語(yǔ)句或函數(shù)。這樣就保證了資源的及時(shí)釋放。

接下來(lái),我們先觀測(cè)新的授權(quán)碼的出現(xiàn),當(dāng)其出現(xiàn)后我們就使用連接讀寫緩存對(duì)象bufrw返回給http客戶端。從觀測(cè)到返回給http客戶端的時(shí)間并不確定,也許時(shí)間會(huì)很長(zhǎng),這也從側(cè)面體現(xiàn)了Long Polling中的Long??聪旅娴拇a:

  1. nacChan := make(chan string) 
  2. triggerFunc := func(newAuthCode string) { 
  3.     nacChan <- newAuthCode 
  4. triggerId := fmt.Sprintf("long-polling|%s|%s|%d", loginName, groupName, time.Now().UnixNano()) 
  5. request.AddNewAuthCodeTrigger(triggerId, triggerFunc) 
  6. defer request.DelNewAuthCodeTrigger(triggerId) 

這段代碼其中包含的東西很多,我們不需要全搞明白,只要知道這是為新授權(quán)碼產(chǎn)生時(shí)間注冊(cè)一個(gè)觸發(fā)器就行了。

當(dāng)新授權(quán)碼被產(chǎn)生后,充當(dāng)觸發(fā)器的函數(shù)triggerFunc會(huì)被調(diào)用。它會(huì)向名為nacChan的Channel中添加一個(gè)元素。注意,這個(gè)Channel是字符串類型的,并且是阻塞式。阻塞式意味著獲取元素的語(yǔ)句會(huì)一直阻塞,直到該Channel被添入元素。另外,當(dāng)Channel中已有一個(gè)元素時(shí),添加元素的語(yǔ)句也會(huì)被阻塞。我們?cè)谶@里只用到了阻塞式Channel的前一個(gè)特性。元素獲取語(yǔ)句是這樣寫的:

  1. newAuthCode := <-nacChan 

獲取到新授權(quán)碼后,程序會(huì)立即把它“push”給http客戶端。

  1. done := pushResponse(bufrw, newAuthCode) 

函數(shù)pushResponse的完整定義如下:

  1. func pushResponse(bufrw *bufio.ReadWriter, authCode string) bool { 
  2.     _, err := bufrw.Write([]byte(authCode)) if err == nil { 
  3.         err = bufrw.Flush() 
  4.     } if err != nil { 
  5.         go_lib.LogErrorf("PushAuthCodeError: %s\n", err) 
  6.         return false  
  7.     }  
  8.     return true  

其中用到了很多“net/http”以外的包,關(guān)于它們的說(shuō)明可以到Go文檔站點(diǎn)http://godoc.org/中查找。另外,“go_lib”是我為了自己開(kāi)發(fā)方便而寫的一個(gè)函數(shù)庫(kù),源碼在這里:https://github.com/hyper-carrot/go_lib,有興趣的讀者可以查看。

至此,基于Long Polling的異步推送服務(wù)的服務(wù)端就完成了。函數(shù)getAuthCodeForAdmin的完整代碼可以參看:https://github.com/hyper-carrot/hypermind/blob/master/server.go#L244。

2.2 編寫客戶端代碼

相應(yīng)的客戶端代碼相當(dāng)簡(jiǎn)單,如下:

  1. $(document).ready(function() { 
  2.     url = "/auth_code" count = 0 function poll_auth_code() { 
  3.         $.ajax({ url: url, success: function(data) { if (count == 0) { 
  4.                 $("#initial").text(data); 
  5.                 url += "?type=lp" } 
  6.             $("#current").text(data); 
  7.             $("#count").text(count); 
  8.             count++ 
  9.         }, dataType: "text", complete: poll_auth_code, timeout: (1000 * 60 * 10) }); 
  10.     } 
  11.     poll_auth_code() 
  12.  }); 

它整體采用了一種基于timeout的循環(huán)機(jī)制,邏輯相當(dāng)簡(jiǎn)單,我在這就不多說(shuō)了,源碼在此:https://github.com/hyper-carrot/hypermind/blob/master/web/page/admin_auth_code.gtpl#L15。

部分頁(yè)面的快照如下圖:

使用Go Hijack和jQuery輕松實(shí)現(xiàn)異步推送服務(wù)

3. 結(jié)束語(yǔ)

怎么樣?很簡(jiǎn)單吧?基于這些代碼,我們還可以實(shí)現(xiàn)更復(fù)雜一些、更有趣的異步推送功能。

在這之后,我試著用Go Hijack和jQuery實(shí)現(xiàn)基于Comet的異步推送,但是由于未找到j(luò)Query中對(duì)HTTP請(qǐng)求響應(yīng)內(nèi)容細(xì)粒度的處理方法,暫時(shí)放棄了。Long Polling對(duì)于我這里的需求來(lái)講是夠用了。

另外再提一點(diǎn)。對(duì)比基于Long Polling方式Comet方式異步推送服務(wù),它們各有利弊。簡(jiǎn)單來(lái)說(shuō),前者會(huì)更多的消耗請(qǐng)求處理資源,后者會(huì)更多的消耗服務(wù)器端口資源。個(gè)人感覺(jué),在大量推送請(qǐng)求的場(chǎng)景下,還是Long Polling方式更好一些,因?yàn)樗鼤?huì)比Comet方式更加及時(shí)的釋放資源。但是,基于Comet方式的異步推送服務(wù)在“push”速度上占有優(yōu)勢(shì),也大大降低了漏掉推送消息的可能性。當(dāng)然,我們可以通過(guò)在基于Long Polling方式的客戶端代碼中設(shè)置足夠長(zhǎng)的timeout時(shí)間來(lái)模仿Comet方式。

最后,我認(rèn)為實(shí)現(xiàn)Comet方式的最佳方式是WebSocket。所以讓我們摒棄掉低版本的網(wǎng)絡(luò)瀏覽器吧!

 

新聞名稱:使用GoHijack和jQuery輕松實(shí)現(xiàn)異步推送服務(wù)
文章鏈接:http://www.rwnh.cn/article14/ghdide.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、微信公眾號(hào)定制開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
绥德县| 永仁县| 华容县| 建阳市| 南乐县| 朝阳县| 焦作市| 黎川县| 通化市| 辉南县| 迁西县| 黄平县| 乌兰察布市| 醴陵市| 鞍山市| 苗栗县| 长丰县| 北辰区| 余姚市| 大方县| 博兴县| 鹤壁市| 台南县| 锡林郭勒盟| 定南县| 新邵县| 台安县| 英德市| 新宾| 平果县| 家居| 丹棱县| 定襄县| 望江县| 新和县| 武义县| 东乌珠穆沁旗| 明星| 化州市| 卓资县| 闸北区|