2011-07-15 48 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