2011-07-15 86 views
1

我想用Java創建自己的WebSocket服務器。Java ServerSocket WebSocket回覆

當我的客戶端連接,我得到以下請求:

(14): GET/HTTP/1.1 
(18): Upgrade: WebSocket 
(19): Connection: Upgrade 
(20): Host: localhost:8483 
(24): Origin: http://localhost 
(45): Sec-WebSocket-Key1: P3$04 H85Zf# 9 9d a0 x10[ 
(34): Sec-WebSocket-Key2: 416393 2 560Y 
(0): 

(括號中的數字,括號,冒號和空格此後,僅是一些我添加了的System.out.println()命令)。括號中的數字是以字節爲單位的行的長度。

我第一次使用此功能處理請求:

public boolean processHandshake(int lineNumber, String line){ 

    if(handshakeProcessed || lineNumber > 9 || lineNumber < 1){ 

     return false; 

    } 

    switch(lineNumber){ 

     case 1:{ handshakeGetLocation = line.replace("GET ", "").replace(" HTTP/1.1", ""); break; } 
     case 2:{ handshakeUpgrade = line.replace("Upgrade: ", ""); break; } 
     case 3:{ handshakeConnection = line.replace("Connection: ", ""); break; } 
     case 4:{ handshakeHost = line.replace("Host: : ", ""); break; } 
     case 5:{ handshakeOrigin = line.replace("Origin: ", ""); break; } 
     case 6:{ handshakeSecWebSocketKey1 = line.replace("Sec-WebSocket-Key1: ", ""); break; } 
     case 7:{ handshakeSecWebSocketKey2 = line.replace("Sec-WebSocket-Key2: ", ""); handshakeProcessed = false; break; } 
     case 8:{ handshakeProcessed = true; } 
     case 9:{ handshakeProcessed = true; } 

    } 

    return true; 

} 

現在,根據this文章,並假設它是我需要處理該協議的第一個版本,我一直在想如何處理商人:

事情是,對於每個鍵,我需要將數字的數量除以空格。我一直在做這樣的:

private double calculateKeyReply(String key){ 

    double numCount = key.replaceAll("[^0-9]", "").length(); 
    double spaceCount = key.replaceAll("[^\\ ]", "").length(); 

    System.out.println(numCount+"/"+spaceCount+"="+numCount/spaceCount); 

    return numCount/spaceCount; 

} 

,並調用下面的函數(replyHandshake()):

String handshake; 

handshake = "HTTP/1.1 101 WebSocket Protocol Handshake\n"; 
handshake += "Upgrade: "+handshakeUpgrade+"\n"; // handshakeUpgrade and the following variables are instance variables I set when I process the request 
handshake += "Connection: "+handshakeConnection+"\n"; 
handshake += "Sec-WebSocket-Origin: "+handshakeOrigin+"\n"; 
handshake += "Sec-WebSocket-Location: "+handshakeOrigin.replace("http", "ws")+handshakeGetLocation+"\n"; 
handshake += "Sec-WebSocket-Protocol: sample\n"; 
// handshake += "\n"; 

String nums = calculateKeyReply(handshakeSecWebSocketKey1)+""+calculateKeyReply(handshakeSecWebSocketKey2); 

MessageDigest md5Digestor = MessageDigest.getInstance("MD5"); 
String md5 = new String(md5Digestor.digest(nums.getBytes())); 

handshake += md5; 

return handshake; 

然後,別的地方:

out.println(replyHandshake()); 

難道我做錯了什麼?我正在使用最新版本的Google Chrome進行測試。

在此先感謝!

+0

您是否實際添加了握手請求的最後幾個字節(在維基百科文章中爲'^ n:ds [4U ')? – pimvdb

+0

你說得對,我一直在做錯。現在我實際上將我得到的前2048個字節存儲到一個字節數組中(可惜,它仍然不起作用,但是:():() – arik

+1

在標題和鍵之間應該有兩個換行符,並且所有換行符都必須是'\ r \ n'而不是'\ n'。 – pimvdb

回答

2

如果您今天從頭開始爲自己付出額外的努力,我會針對最新版本的協議(版本8,草案10)。

上述握手是來自過時的版本。

Chrome 14和Firefox 7/8支持最新版本。 Firefox 6有一個(默認禁用)舊版本。 Chrome可能會很好地支持任何版本< 8.

+0

啊,有趣。謝謝! – arik