Java中的”推”技術
bromon原創 著作權
在一般的B/S程式中(最典型的是web服務),工作的方式是用戶端(brower)向伺服器端(server)發送一個請求,伺服器端響應這個請求並發回用戶端所請求的資料。在這個過程中伺服器端扮演的是一個被動響應的角色,一般的情況下,伺服器端是不會主動向用戶端寫資料的。由於HTTP是一個不需連線的協議,也就是說當伺服器端完成對用戶端的響應後,雙方的串連就斷開了,直到下一次用戶端發出請求時再重建立立串連。這樣的HTTP協議是節省網路資源的,但是也給我們帶來了一些麻煩,比如用戶端不能即時探查伺服器端的資料變化,不能作出及時的響應。所以當我們在做一些需要用戶端和伺服器端互相響應的程式時(比如聊天室、web簡訊息),不得不在用戶端不停的重新整理頁面,以求獲得最新的資料,這樣做增加的伺服器的負擔。如果伺服器能在資料發生變化的時候主動向用戶端寫資料,那麼問題就解決了,這就是所謂的“推”技術。
在java中,用戶端主動向伺服器端申請資料,叫做“拉”;伺服器主動向用戶端寫資料,叫做“推”。我們可以在伺服器端開啟某個連接埠,監聽用戶端的串連,就可以向用戶端隨意寫資料,這是我們做C/S程式的原理,“推”技術採用相同的原理,只是用戶端是瀏覽器而已,只要我們按照瀏覽器能夠識別的格式向用戶端寫資料,用戶端就可以通過HTTP與伺服器建立串連,並獲得資料。
HTTP是一個很龐大的協議,但是我們只需要用到很小一部分。最重要的是要知道按照什麼格式寫資料,瀏覽器才認識。當我們瀏覽一個網站的某一頁,比如www.sohu.com/page.htm的時候,我們是在向伺服器發送這樣一個資訊:
GET /page.htm HTTP/1.0
From: someuser@somehost.com
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0; DigExt)
空行
其中第一行是我們要關注的,它由空格分隔成三部分,一是請求的方法(get),二是請求的頁面,三是HTTP的版本。如果請求無誤,伺服器將返回如下資訊:
HTTP/1.0 200 OK
Date: Thu, 8 Oct 2002 14:23:11 GMT
Content-Type: text/html
Content-Length: 1644
<html>
<body>
<h1>Hello world!</h1>
(其他內容)...
</body>
</html>
第一行表示串連成果,然後是返回資料的屬性,從<html>開始才是返回給瀏覽器返回的資料。在我們自己的程式中只需要按照上述格式寫資料,就可以實現一個自己的簡易web伺服器。下面是一個hello,world的例子:
//myServer.java
import java.io.*;
import java.net.*;
public class myServer
{
static ServerSocket server=null;
static OutputStreamWriter ow=null;
public static void main(String args[])
{
int port=800;
try
{
server=new ServerSocket(port);
}catch(Exception e)
{
System.out.println(e);
}
while(true)
{
try
{
Socket socket=server.accept();
ow=new OutputStreamWriter(socket.getOutputStream());
ow.write("HTTP/1.0 200 ok ");
ow.write("Content-Type:text/html ");
ow.write("<html><body>");
ow.write("hello,world");
ow.write("</body></html>");
ow.flush();
socket.close();
}catch(Exception e)
{
System.out.println(e);
}
}
}
}
編譯:javac myServer.java
運行:java myServer
然後開啟瀏覽器,輸入http://localhost:800,將會返回一個”hello,world”
以上就是一個“推”技術的簡單實現,將它擴充一下,比如加入多線程響應,就可以實現無重新整理的聊天室,請讀者自己考慮。
原文發表於《程式春秋》0301期