server push具體實現(轉)

來源:互聯網
上載者:User
server 拙作“推”向更快發表後,筆者收到了很多朋友的來信,希望能瞭解更多的關於 SERVER PUSH的技術資料,說實話對這一新技術筆者也不是太瞭解,但本著知無不言的思想,在這雷根據筆者的實際使用方式作一些詳細的介紹,希望給那些對 SERVER PUSH有興趣的朋友一點點的協助和參考。也希望能藉此拋磚引玉,求得高手的不吝指教。
   
  “推”由於篇幅的原因,只對 SERVER PUSH作了一般的介紹,下面我們來看看SERVER PUSH的具體實現過程:
  一、作業系統:
  目前 SERVER PUSH還不能在WIN9X上實現,至少是我自己還沒有在WIN9X作為主機上實現過這一功能。經筆者實驗成功的作業系統有:WINNT4.0,UNIX,LINUX,FREEBSD,以LINUX支援最好。因為我使用的LINUX都是最新的版本,可以方便地編譯最新的功能模組。當然還有其它的作業系統也能很好地支援 SERVER PUSH功能,但筆者限於條件沒有測試過。
  二、WWW伺服器:
  其實目前除了IIS和APACHE這兩個WWW伺服器,你沒有更好的選擇,值得慶辛的是它們都能很好地支援 SERVER PUSH,當然你應該選擇它們的最新版。別的那些小孩子過家家那樣的WWW伺服器就不用試了。在這裡筆者極力推薦在LINUX上安裝APACHE,以便能自由編譯功能模組,這樣可以充分使用SERVER PUSH、FASTCGI、E-CGI、HPH等新的擴充功能。
  三、指令碼支援:
  雖然 SERVER PUSH可以用更多的指令碼程式來編寫,但筆者強烈推薦用PERL或C語言來寫CGI指令碼,因為PERL已經是CGI指令碼程式事實上的標準。而且在PERL5中已經可以直接調用C子程式而不需要任何聲明。不管你用什麼語言來寫CGI指令碼,解譯器中應該有CGI.PM模組,筆者試用的版本是 5.004,這一模組的更新版大家可以從網上下載,找不到?用搜尋引擎輸入CGI.PM就行了,要多少個都有。
  好了,有了上面的工具,下面我們就來寫一個 SERVER PUSH程式來說明它的實現過程:
#!/usr/bin/perl
use CGI qw/:push -nph/;
$| = 1;
print multipart_init(-boundary=>'--boundary');
while (1) {
  print multipart_start(-type=>'text/plain'),
  "The current time is ",scalar(localtime),"n",
  multipart_end;
  sleep 1;
}
  use CGI qw/:push -nph/;這一行告訴CGI解釋程式,調用支援SERVER PUSH的功能模組(CGI.PM),在這個模組中預先定義了三個涵數:multipart_init()、multipart_start()和multipart_end,只要在程式中有use CGI qw/:push -nph/聲明。就可以直接使用這三個涵數。
  multipart_init()涵數的作用是聲明了一個文件類型,就象普通的CGI程式中的“Content-Type: text/html”聲明,告訴伺服器下面傳送的是HTML文檔,而multipart_init()這一涵數聲明的檔案類型卻是實現SERVER PUSH最根本的方法類型:Content-Type: multipart/x-mixed-replace; boundary='--boundary'如果你對HTTP的MIME類型有詳細的瞭解,你就知道multipart類型是一種複合類型,它的子類型是mixed,子類型的X參數大家可以參看詳細的MIME類型說明,這裡最關鍵的是replace方法,它不停地用新接收的資料更新舊的資料。這,就是SERVER PUSH最大的技術內涵。boundary只是一個邊界值,告訴瀏覽器從這兒開始,使用SERVER PUSH方法了。其實你完全可以這樣理解,只要在指令碼程式中聲明了multipart/x-mixed-replace; boundary='--boundary'這樣一個文件類型,伺服器就和客戶機建立了一個特別的連結。伺服器就不斷地把客戶機請求的資料來源源不斷地推向了客戶機。而傳統的CLIENT PULL方法是:1、CLIENT和SERVER建立連結。2、CLIENT發送請求。3、SERVER響應請求。4、SERVER斷開連結以響應下一請求。通過這兩種方法的比較大家可以看出SERVER PUSH優點主要在於伺服器和客戶機之間這種不間斷的連結方式。使得它不需要採用CLIENT PULL的<META http-equiv=refresh content="n">這種方法來重新整理頁面,不僅更新速度快,而且不會產生閃動效果。
  可以看到,如果你不用multipart_init(),直接在指令碼程式中用這樣的語句也可以達到同樣的目的:
print "Content-Type: multipart/x-mixed-replace;boundary='boundary'nn"
這樣做的好處是當系統不能支援multipart_init()涵數時,就可以直接這樣聲明.
  multipart_start()這個涵數是為伺服器指定了傳送一個確定的文檔,如果不用這個涵數,根據指令碼程式的內容伺服器可以直接把指定資料傳送給客戶機,當然客戶機不能識別這種類型的文檔可以忽略而不會產生錯誤。但如果你指明了具體的文件類型,如常式中的text/plain(純文字類型),客戶機就不要再對文檔加以分析從而提高了處理速度。否則客戶機只知道傳送過來的是multipart(複合型)而要重新對其分析。
  至於multipart_end涵數不需作詳細說明,只是說明了一個PUSH過程的結束。

  為了使大家能更好地理解這三個涵數詳細的技術內容,我把這三個涵數的實現過程解析給大家:
  sub multipart_init {
  my($self,@p) = self_or_default(@_);
  my($boundary,@other) = $self->rearrange([BOUNDARY],@p);
  $boundary = $boundary || '------- =_aaaaaaaaaa0';
  $self->{'separator'} = "n--$boundaryn";
  $type = SERVER_PUSH($boundary);
  return $self->header(
-nph => 1,
-type => $type,
(map { split "=", $_, 2 } @other),
  ) . $self->multipart_end;
  }

  sub multipart_start {
  my($self,@p) = self_or_default(@_);
  my($type,@other) = $self->rearrange([TYPE],@p);
  $type = $type || 'text/html';
  return $self->header(
-type => $type,
(map { split "=", $_, 2 } @other),
  );
  }
  
  sub multipart_end {
  my($self,@p) = self_or_default(@_);
  return $self->{'separator'};  
  }  
  其它的在使用SERVER PUSH時的一些技巧,限於篇幅我不能再作過多的介紹,大家可以到下面地址看看我用SERVER PUSH寫的聊天室,歡迎有興趣的朋友和我交流。
  聊天室地址:http://wangjh.3322.net/chat.htm,保密哦,這是一個免費個人首頁空間,不讓放聊天室,網管知道了就會DEL了的。

原作者:wangjinhua  
來源:http://bj.netease.com   



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。