標籤:tchar cte sys content 用戶端 stat lib 頻寬 .net
為了實現服務端向用戶端推送的模式,如果自己寫的socket到時順理成章的很容易實現。但是,甲方要我們用標準的http協議。當然,自己寫http伺服器倒是也沒什麼題,我開始也時這麼想的,而且都設計好了分布計算和Server Load Balancer的方式。但有人暫時還建議我們用中介軟體,他們的意見就像天氣的臉,一會兒這樣,一會兒那樣。於是在這方面考慮,無奈和喜悅同時而生。無奈的是,直接應用中介軟體,成就感將大打折扣。喜悅的是,直接應用中介軟體,我的開發量幾乎可以說就是實現商業邏輯,分布計算和Server Load Balancer都可以配置中介軟體實現。
那麼如果用中介軟體寫http服務,來應付用戶端的請求並實現推送模式呢。在開會的時候, 一個同事使我猛醒。他說他就直接寫一個servlet,這就是標準的http服務。這時,我便想起了我曾寫過用Java中URL累實現的http用戶端。不妨用之,這樣服務端用戶端就都有了實驗的依據。其中我問及同事是否實現長串連,結果他說沒有 (應該是沒想到這點),但是我們知道,服務推送的模式每次都開啟和關閉與用戶端的串連必然很耗資源。而我們實現的系統就是具備長串連,而且很耗頻寬的串連,不管是長串連還是短串連。如果每次資料傳送都要建立串連,而且請求非常頻繁的假推送模式效能很低的話,我們就可以試一試長串連推送的方式。
也許你會想,servlet的長串連怎麼實現呢。不錯,用while迴圈就可以了。平常我們用瀏覽器瀏覽網頁,大都一次請求,然後得到結果,關閉串連。其實如果服務端用一個死迴圈,一直在發送資料,而且用戶端沒有關閉的話,串連是一直存在的。我們完全可以用這條串連實現服務推模式。當然,監聽的用戶端自己寫一個很簡單,如下:
Java代碼
- package test;
-
- import java.io.InputStream;
- import java.net.URL;
-
- public class LongConnectionClient {
-
- public static void main(String args[]) {
- try {
-
- //確定服務地址
- URL url = new URL("http://localhost:8080/HttpConnectionTest/LongConnectionTest");
- InputStream in=url.openStream();
- int n = -1;
- byte[] b = new byte[1024];
- //從服務端讀取資料並列印
- while((n=in.read(b))!=-1)
- {
- String s=new String(b,0,n, "UTF-8");
- System.out.println(s);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- }
服務端的代碼也異常簡單:
Java代碼
- package test;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class LongConnectionTest extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
- static final long serialVersionUID = 1L;
-
- public LongConnectionTest() {
- super();
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- this.doPost(request, response);
- }
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- response.setCharacterEncoding("UTF-8");
- response.setContentType("text/html");
-
- PrintWriter pr = response.getWriter();
-
- try {
- while(true) {
- pr.print("有時候你不得不相信");
- //flush的作用很重要,當你任務寫給用戶端的資料總夠多的時候
- //調用之,用戶端方能讀取到。
- //否則,在資料長度達到上限或者串連關閉之前,用戶端讀不到資料
- pr.flush();
- Thread.sleep(500);
- }
- } catch(Exception e) {
- e.printStackTrace();
- }
-
- }
- }
用 servlet實現http長串連