HTTP實現長鏈接(TTP1.1和HTTP1.0相比較而言,最大的區別就是增長了持久鏈接支持Connection: keep-alive)

HTTP實現長鏈接

 

HTTP是無狀態的 
也就是說,瀏覽器和服務器每進行一次HTTP操做,就創建一次鏈接,但任務結束就中斷鏈接。若是客戶端瀏覽器訪問的某個HTML或其餘類型的Web頁中包含有其餘的Web資源,如JavaScript文件、圖像文件、CSS文件等;當瀏覽器每遇到這樣一個Web資源,就會創建一個HTTP會話html

HTTP1.1和HTTP1.0相比較而言,最大的區別就是增長了持久鏈接支持(貌似最新的 http1.0 能夠顯示的指定 keep-alive),但仍是無狀態的,或者說是不能夠信任的。java

若是瀏覽器或者服務器在其頭信息加入了這行代碼web

Connection:keep-aliveajax

TCP鏈接在發送後將仍然保持打開狀態,因而,瀏覽器能夠繼續經過相同的鏈接發送請求。保持鏈接節省了爲每一個請求創建新鏈接所需的時間,還節約了帶寬。apache

實現長鏈接要客戶端和服務端都支持長鏈接。promise

若是web服務器端看到這裏的值爲「Keep-Alive」,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久鏈接),它就能夠利用持久鏈接的優勢,當頁面包含多個元素時(例如Applet,圖片),顯著地減小下載所須要的時間。要實現這一點, web服務器須要在返回給客戶端HTTP頭信息中發送一個Content-Length(返回信息正文的長度)頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然 後在正式寫出內容以前計算它的大小瀏覽器

不管客戶端瀏覽器 (Internet Explorer) 仍是 Web 服務器具備較低的 KeepAlive 值,它都將是限制因素。例如,若是客戶端的超時值是兩分鐘,而 Web 服務器的超時值是一分鐘,則最大超時值是一分鐘。客戶端或服務器均可以是限制因素tomcat

在header中加入 --Connection:keep-alive 
在HTTp協議請求和響應中加入這條就能維持長鏈接。 
再封裝HTTP消息數據體的消息應用就顯的很是簡單易用安全

Http Keep-Alive seems to be massively misunderstood. Here's a short description of how it works, under both 1.0 and 1.1服務器

HTTP/1.0

Under HTTP 1.0, there is no official specification for how keepalive operates. It was, in essence, tacked on to an existing protocol. If the browser supports keep-alive, it adds an additional header to the request:

ConnectionKeep-Alive

Then, when the server receives this request and generates a response, it also adds a header to the response:

ConnectionKeep-Alive

Following this, the connection is NOT dropped, but is instead kept open. When the client sends another request, it uses the same connection. This will continue until either the client or the server decides that the conversation is over, and one of them drops the connection.

HTTP/1.1

Under HTTP 1.1, the official keepalive method is different. All connections are kept alive, unless stated otherwise with the following header:

Connection: close

The ConnectionKeep-Alive header no longer has any meaning because of this.

Additionally, an optional Keep-Alive: header is described, but is so underspecified as to be meaningless. Avoid it.

Not reliable

HTTP is a stateless protocol - this means that every request is independent of every other. Keep alive doesn’t change that. Additionally, there is no guarantee that the client or the server will keep the connection open. Even in 1.1, all that is promised is that you will probably get a notice that theconnection is being closed. So keepalive is something you should not write your application to rely upon.

KeepAlive and POST

The HTTP 1.1 spec states that following the body of a POST, there are to be no additional characters. It also states that "certain" browsers may not follow this spec, putting a CRLF after the body of the POST. Mmm-hmm. As near as I can tell, most browsers follow a POSTed body with a CRLF. There are two ways of dealing with this: Disallow keepalive in the context of a POST request, or ignore CRLF on a line by itself. Most servers deal with this in the latter way, but there's no way to know how a server will handle it without testing.

 

Java應用

client用apache的commons-httpclient來執行method 。 
用 method.setRequestHeader("Connection" , "Keep-Alive" or "close") 來控制是否保持鏈接。

 

經常使用的apache、resin、tomcat等都有相關的配置是否支持keep-alive。

 

tomcat中能夠設置:maxKeepAliveRequests

 

The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well asHTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.



解釋1

所謂長鏈接指創建SOCKET鏈接後不論是否使用都保持鏈接,但安全性較差,   
所謂短鏈接指創建SOCKET鏈接後發送後接收完數據後立刻斷開鏈接,通常銀行都使用短鏈接

 

解釋2

長鏈接就是指在基於tcp的通信中,一直保持鏈接,無論當前是否發送或者接收數據。   
而短鏈接就是隻有在有數據傳輸的時候才進行鏈接,客戶-服務器通訊/傳輸數據完畢就關閉鏈接。

 

解釋3

長鏈接和短鏈接這個概念好像只有移動的CMPP協議中提到了,其餘的地方沒有看到過。   
通訊方式   
各網元之間共有兩種鏈接方式:長鏈接和短鏈接。所謂長鏈接,指在一個TCP鏈接上能夠連續發送多個數據包,在TCP鏈接保持期間,若是沒有數據包發送,須要雙方發檢測包以維持此鏈接。短鏈接是指通訊雙方有數據交互時,就創建一個TCP鏈接,數據發送完成後,則斷開此TCP鏈接,即每次TCP鏈接只完成一對 CMPP消息的發送。   
現階段,要求ISMG之間必須採用長鏈接的通訊方式,建議SP與ISMG之間採用長鏈接的通訊方式。

 

解釋4

短鏈接:好比http的,只是鏈接、請求、關閉,過程時間較短,服務器如果一段時間內沒有收到請求便可關閉鏈接。   
長鏈接:有些服務須要長時間鏈接到服務器,好比CMPP,通常須要本身作在線維持。



最近在看「 服務器推送技術」,在B/S結構中,經過某種magic使得客戶端不須要經過輪詢便可以獲得服務端的最新信息(好比股票價格),這樣能夠節省大量的帶寬。
 
     傳統的輪詢技術對服務器的壓力很大,而且形成帶寬的極大浪費。若是改用ajax輪詢,能夠下降帶寬的負荷(由於服務器返回的不是完整頁面),可是對服務器的壓力並不會有明顯的減小。
 
    而推技術(push)能夠改善這種狀況。但由於 HTTP鏈接的特性(短暫,必須由客戶端發起),使得推技術的實現比較困難,常見的作法是經過延長http鏈接的壽命,來實現push。
 
    接下來天然該討論如何延長 http鏈接的壽命,最簡單的天然是死循環法:
 
    【servlet代碼片斷】
     public void doGet(Request req, Response res) {
          PrintWriter out = res.getWriter();
          ……
          正常輸出頁面
          ……
          out.flush();
          while (true) {
                out.print("輸出更新的內容");
                out.flush();
                Thread.sleep(3000);
          }
      }
 
     若是使用觀察者模式則能夠進一步提升性能。
 
     可是這種作法的缺點在於客戶端請求了這個servlet後,web服務器會開啓一個線程執行servlet的代碼,而servlet由遲遲不願結束,形成該線程也沒法被釋放。因而乎,一個客戶端一個線程,當客戶端數量增長時,服務器依然會承受很大的負擔。
 
     要從根本上改變這個現象比較複雜,目前的趨勢是從web服務器內部入手,用 nio(JDK 1.4提出的java.nio包)改寫request/response的實現,再利用線程池加強服務器的資源利用率,從而解決這個問題,目前支持這一非J2EE官方技術的服務器有 GlassfishJetty(後者只是據說,沒有用過)。
 
     目前也有一些框架/工具能夠幫助你實現推功能,好比pushlets。不過沒有深刻研究。
 
     這兩天準備學習一下Glassfish中對Comet(彗星:某人給服務器推送技術起的名字)的支持,呵呵。

http://www.cnblogs.com/lidabo/p/4585900.html

相關文章
相關標籤/搜索