概述
HTML5 WebSockets是HTML5中最强大的通信功能,它定义了一个全双工通信信道,仅通过Web上的一个Socket即可进行通信。
目前实时Web应用的实现方式,大部分是围绕轮询和其他服务器端推送技术展开的,Comet、轮询、长轮询、流(streaming)解决方案,所有这些提供实时数据的方式包含有大量额外的、不必要的报头数据,会造成传输延迟。最重要的是为了在半双工HTTP的基础上模拟全双工通信,目前的许多解决方案都是使用了两个连接:一个用于下行数据流,另一个用于上行数据流。这两个连接的保持和协作也会造成大量的资源消耗,并增加了复杂度。
WebSockets就是解决以上问题的方案。为了建立WebSocket通信,客户端和服务器在初始握手时,将HTTP协议升级到WebSocket协议。
现在WebSocket服务器有很多,还在开发中的更多。有一下几种:
Kaazing WebSocket Gateway:一种基于Java的WebSocket网关。
mod_pywebsocket:一种基于Python的Apache HTTP服务器扩展。
Netty:一种包含WebSocket的Java框架。
node.js:一种驱动多个WebSocket服务器的服务器端JavaScript框架。
对于非原生支持WebSocket的浏览器来说,Kazzing的WebSocket网关包含了完整的客户端浏览器WebSocket模拟支持。
主要代码
1.引入jar文件:
2.javascript代码:
HOME_PAGE.myWebSocket = {
ws:null,
url:"ws://localhost:8088/WeatherDisaster/mojiWebsocket",
connect:function () {
if (this.ws != null) {
log("现已连接");
return ;
}
//url = "ws://localhost:8080/WeatherDisaster/mojiWebsocket";
if ('WebSocket' in window) {
this.ws = new WebSocket(this.url);
} else if ('MozWebSocket' in window) {
this.ws = new MozWebSocket(this.url);
} else {
alert("您的浏览器不支持WebSocket。");
return ;
}
this.ws.onopen = function() {
console.log("WebSocket已连接");
//设置发信息送类型为:ArrayBuffer
//ws.binaryType = "arraybuffer";
//发送一个字符串和一个二进制信息
//ws.send("thank you for accepting this WebSocket request");
//var a = new Uint8Array([8, 6, 7, 5, 3, 0, 9]);
//ws.send(a.buffer);
}
this.ws.onmessage = function(e) {
console.log(e.data.toString());
}
this.ws.onclose = function(e) {
console.log("WebSocket已关闭");
}
this.ws.onerror = function(e) {
console.log("WebSocket出错");
}
},
doSend:function(msg){
if (this.ws != null){
this.ws.send(message);
}
},
disconnect:function() {
if (this.ws != null) {
this.ws.close();
this.ws = null;
}
}
}
3.javascript代码使用:
//页面加载完执行事件,比$function后执行。
window.onload = function() {
HOME_PAGE.myWebSocket.connect();
}
window.onbeforeunload = function(event) {
HOME_PAGE.myWebSocket.disconnect();
console.log("onbeforeunload:websorcket关闭");
}
4.java服务端代码
@ServerEndpoint("/mojiWebsocket")
public class MoJiSocket {
private Session session;
private Timer timer = null;
private static final Random random = new Random();
//throws IOException, InterruptedException
@OnMessage
public void onMessage(String message, Session session) {
try {
if (session.isOpen()) {
System.out.println("服务端接收到信息: " + message);
session.getBasicRemote().sendText("服务端接收到客户端发来的信息");
// Send 3 messages to the client every 5 seconds
/*int sentMessages = 0;
while(sentMessages < 3){
Thread.sleep(5000);
session.getBasicRemote().
sendText("This is an intermediate server message. Count: "
+ sentMessages);
sentMessages++;
}*/
}
} catch (IOException e) {
try {
session.close();
} catch (IOException e1) {
// Ignore
e1.printStackTrace();
}
}
}
@OnOpen
public void onOpen (Session session) {
this.session = session;
try {
System.out.println("客户端已连接");
if (session.isOpen()) {
//设置心跳发送信息。每2秒发送一次信息。
timer = new Timer(true);
timer.schedule(task, 1000, 2000);
}
} catch (Exception e) {
try {
session.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@OnClose
public void onClose () {
try {
System.out.println("连接已关闭");
if (timer != null) {
timer.cancel();
}
} catch(Exception e) {
//session.close();
e.printStackTrace();
}
}
public void sendMsg(String msg) {
try {
if (session.isOpen()) {
this.session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
try {
this.session.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
/**
* 发送随机数任务。
*/
TimerTask task = new TimerTask() {
public void run() {
long param = random.nextInt(100);
sendMsg(String.valueOf(param));
}
};
}
注意事项
1.需在tomcat7以上运行
2如果出现以下错误,表示浏览器关闭时,没有将websorcket关闭。
引用
1.HTML5学习笔记(七)-WebSockets API
2.WebSocket的JavaScript例子
3.WebSocket 教程