先说WebSocket的客户端,用Javascript写就行var websocekt=new WebSocket("ws://127.0.0.0:8888");//8888是端口号
websocket.onopen=function(event){
//...当连接成功会执行这里的代码
}
对于WebSocket,连接成功是实现握手。
服务端先运行着,这边打开客户端,客户端建立websocket,就会向其指定的服务端地址端口发送一个
HTTP请求,大概如下:GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:8888
Origin: null
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: CoIrEpLMznRgAYho/n3ooQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
这就是客户端建立websocket时发往服务端的请求消息
服务端也要加应一个相应的消息到客户端,成功了才算握手成功,才能开始正式的通信
注意其中的Sec-WebSocket-Key
服务端返回握手信息需要用到这个Key,拿这个Key生成一个Sec-WebSocket-Accept,加到返回信息中回送给客户端
我们建个服务端public class Server {
public Server() throws Exception{
ServerSocket ss=new ServerSocket(30000);
Socket socket=ss.accept();
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
byte[] buff=new byte[1024];
int count=-1;
String req="";
count=in.read(buff);
req=new String(buff, 0, count);
System.out.println("握手请求:"+req);
String secKey=getSecWebSocketKey(req);
System.out.println("secKey="+secKey);
String response="HTTP/1.1 101 Switching Protocols\r\nUpgrade: "
+"websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "
+getSecWebSocketAccept(secKey)+"\r\n\r\n";
System.out.println("Sec-Accept="+getSecWebSocketAccept(secKey));
out.write(response.getBytes());
count=in.read(buff);
System.out.println("接收的字节数:"+count);
for(int i=0;i
buff[i+6]=(byte)(buff[i%4+2]^buff[i+6]);
}
System.out.println("接收的内容:"+new String(buff, 6, count-6, "UTF-8"));
byte[] pushHead=new byte[2];
pushHead[0]=buff[0];
String pushMsg="收到!收到!欢迎加入WebSocket世界!";
pushHead[1]=(byte)pushMsg.getBytes("UTF-8").length;
out.write(pushHead);
out.write(pushMsg.getBytes("UTF-8"));
socket.close();
ss.close();
}
private String getSecWebSocketKey(String req){
Pattern p=Pattern.compile("^(Sec-WebSocket-Key:).+",Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
Matcher m=p.matcher(req);
if(m.find()){
String foundstring=m.group();
return foundstring.split(":")[1].trim();
}
else{
return null;
}
}
private String getSecWebSocketAccept(String key) throws Exception{
String guid="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
key+=guid;
MessageDigest md=MessageDigest.getInstance("SHA-1");
md.update(key.getBytes("ISO-8859-1"),0,key.length());
byte[] shaHash=md.digest();
BASE64Encoder encoder=new BASE64Encoder();
return encoder.encode(shaHash);
}
public static void main(String[] args) throws Exception{
new Server();
}
}
其中Base64Encoder是在包sun.misc下,eclipse下需要在项目的BuildPath中对JRE中的Access rules进行设置。
页面这边
var webSocket=new WebSocket("ws://127.0.0.1:8888");
webSocket.onopen=function(){
alert("已打开连接");
webSocket.send("我是谁");
};
webSocket.onmessage=function(event){
alert("收到的消息是:"+event.data);
};
webSocket.onclose=function(event){
alert("close");
};
先运行Server,再打开网页就会看到效果