WebSocket
1)轮询(JavaScript中的setInterval) 最简单的是前台轮询,每隔一段时间去请求后台,以获取最新状态,这种方式最容易实现,但效果也最差,频繁盲目的调用后台,带来不必要的开销,且实时性无法保障,后台出现更新,前端需要在下一次轮询时才知道。
2)长轮询 为了解决这些弊端,进化出长轮询技术,轮询请求会在后台阻塞,相当于保持一个长连接,直到后台出现更新或者超时才返回,这样就可以保证更新的及时性,前端得到请求后,重新建立轮询连接,等待后台的更新通知。
但这几种模式:实现上复杂,效率低效,资源浪费,并非做到真正的实时。
html5规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用WebSocket技术,后台可以随时向前端推送消息,以保证前后台状态统一,在传统的无状态HTTP协议中,这是“无法做到”的。WebSocket的服务器链接形式为:"ws://localhost:8080/hello-websocket/hello"
使用JavaScript检测:
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket){
alert("WebSocket not supported by this browser");
return;
}
附图:
服务器支持附图:
1、Client发送握手请求;
2、Server返回握手应答;
3、连接之后,开始进行消息通信;
附图:
WebSocket#onopen, onmessage, onclose, onerror
连接打开时,回调onopen方法,接收到后台消息时会触发到onmessage事件,后台关闭时调用onclose,出现连接异常时可在onerror中捕获。
发送消息 – WebSocket#send(data) 关闭连接 – WebSocket#close(optional code, optional reason)
发送消息例子:
websocket.send(JSON.stringify({action: "node.remove", id: "001"}));
var wsUri = "ws://localhost:8080/hello-websocket/hello";
var websocket = new WebSocket(wsUri);
# 处理建立连接事件
websocket.onopen = function(evt) { onOpen(evt) };
# 处理接收信息事件
websocket.onmessage = function(evt) { onMessage(evt) };
# 处理出错事件
websocket.onerror = function(evt) { onError(evt) };
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/hello")
public class HelloBean {
@OnMessage
public String sayHello(String name) {
return "Hello " + name + "!";
}
}
1)Java API 规范
– http://jcp.org/en/jsr/detail?id=356 – http://java.net/projects/websocket-spec – Included in Java EE 7
2)参考实现
– http://java.net/projects/tyrus – Bundled with Glassfish 4
1,两种方式创建 Endpoints
– Interface-driven (Endpoint) – Annotation-driven (@ServerEndpoint)
2,提供客户端,服务端的API
3,SPI for extensions and data frames(不太理解)
Endpoint: Intercepts WebSocket lifecycle events
MessageHandler: Handles all incoming messages for an Endpoint
RemoteEndpoint: Represents the ‘other end’ of this conversation
Session: Represents the active conversation
- Server:
public class HelloServer extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig configuration) {
session.addMessageHandler(
new MessageHandler.Whole<String>() {
public void onMessage(String name) {
try {
session.getBasicRemote().sendText(“Hello “ + name);
} catch (IOException ioe) {
// Handle failure.
}
}
});
}
}
- Client:
public class HelloClient extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig configuration) {
try {
session.getBasicRemote().sendText("Hello you!");
} catch (IOException ioe) {
. . .
}
}
}
- 使用示例
@ServerEndpoint("/hello")
public class HelloBean {
@onMessage
public String sayHello(String name){
return "Hello" + name;
}
}
- WebSocket Annotations 接口介绍
1,@ServerEndpoint,将一个类声明为WebSocket的服务器端点
2,@ClientEndpoint,将一个类声明为WebSocket的客户端点
3,@OnOpen,拦截 WebSocket 打开事件
4,@OnClose,拦截WebSocket关闭事件
5,@OnMessage,拦截WebSocket的消息事件
6,@PathParam,一个URI模板的标记匹配的路径段
7,@OnError,拦截在一个会话当中的出现的错误
关于WebSocket的更多介绍,可以查看:http://docs.oracle.com/javaee/7/tutorial/doc/websocket.htm