websocket是一种持久化的协议,在建立起连接之后,和服务器就产生了一个通道,之后客户端和服务端的会话,都在这个通道中进行,而不会发起新的请求。协议头不再是http://开头的,而是以ws://进行开头,状态码是101。
websocket主要有3个事件,建立连接的open事件,发送消息的message事件以及关闭连接的close事件。在客户端new websocket(url)对象时便触发了建立连接事件,使用websocket.send(str)时,触发发送消息事件,退出时触发关闭事件。
在java后端,使用@ServerEndpoint("/addr")注解将目前的类定义成一个websocket服务器端,注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端。这个类是多例的,每有一个连接建立时,便产生一个新的对象,使用静态变量来存储多个实例的共享数据(也可以访问数据库来替代静态变量)。
在该类中,可以分别定义多个方法,在方法上加上@OnOpen注解就代表建立websocket连接时触发的方法,方法中接收一个javax.websocket.Session的参数,加上注解之后,该方法为回调方法,可以相应的session数据。同理,还有@OnMessage、@OnClose等注解。
以下为一个简单的websocket演示,先建立连接,然后向服务端发送消息,服务端返回消息,客户端再主动断开连接。
详细代码:
> JSP代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>first websocket</title>
</head>
<body>
<button onclick="conn();">conn</button>
<input type="text" id="msg"/><button onclick="send();">send</button>
<button onclick="closeWS();">close</button>
<div id="div">
</div>
</body>
<script type="text/javascript">
var ws;//一个ws对象,就是一个通信管道
var target = "ws://localhost:8080/websocket/echo";
function conn(){
if ('WebSocket' in window) {
ws = new WebSocket(target);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(target);
} else {
alert('WebSocket is not supported by this browser.');
return;
}
if(ws!=null){
var div = document.getElementById("div");
div.innerHTML+="websocket连接成功!<br/>";
}
//注册事件,异步接收服务端消息
ws.onmessage = function(event){
console.info(event);
var div = document.getElementById("div");
div.innerHTML+=event.data+"<br/>"; //event.data为服务器返回的数据
};
}
function send(){
var msg = document.getElementById("msg").value;
ws.send(msg);
document.getElementById("msg").value = "";
var div = document.getElementById("div");
div.innerHTML+="client:"+msg+"<br/>";
}
function closeWS(){
ws.close();
var div = document.getElementById("div");
div.innerHTML+="websocket连接关闭<br/>";
}
</script>
</html>
> JAVA代码:
/**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
*/
@ServerEndpoint("/echo")
public class EchoSocket {
public EchoSocket() {
System.out.println("多例");
}
//静态变量,用来记录当前在线连接数。
private static int onlineCount = 0;
//打开连接时事件
@OnOpen
public void open(Session session) {
//一个session就代表一个通信的会话
System.out.println("session id:"+session.getId());
onlineCount++;
System.out.println("新用户加入,当前在线人数: "+onlineCount);
}
//关闭连接时事件
@OnClose
public void close(Session session) {
//一个session就代表一个通信的会话
System.out.println("session id:"+session.getId()+" close");
onlineCount--;
System.out.println("有用户退出,当前在线人数: "+onlineCount);
}
//发送消息事件
@OnMessage
public void message(Session session,String msg) {
//打印客户端消息
System.out.println("session id:"+msg);
//服务端向客户端发消息
try {
session.getBasicRemote().sendText("server: "+msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}