简介
传统的网络通信一般使用的是HTTP协议,它是一种无状态的、无连接的、单向的应用层协议。通信请求只能由客户端发起,服务端对请求做出应答处理。它是单向的,也就导致无法实现服务器主动向客户端发起消息。同时,它也是一次性的,即每个请求响应后,连接就结束了。要想继续与服务端对话,就需要重新发送请求。
但有些时候,我们是需要前后端保持长久的、双向的联系,前端实时获取后端推送过来的信息,而不是自己去发送一个个的请求来获取。
这时,webSocket就应运而生了。
webSocket:实现了浏览器与服务器全双工通信(full-duplex)。只需要建立一次连接,就可以一直保持连接状态,并且前后端可以互相通信,不再是单向的了。
简单使用
webSocket使用起来其实很简单,下面简单介绍一下:
-
前端:调用websocket方法进行连接和各种状态下的通信:
new WebSocket("ws://localhost:/websocket");
其中 /websocket 是后台定义的
其余的各种方法,看下面例子即可 -
后端:定义一个websocket服务端
@ServerEndpoint("/websocket") public class WebSocketTest {}
@ServerEndpoint
注解是一个类层次的注解,将目前的类定义成一个websocket服务器端,
注解的值
即为访问的URL地址,即前端ws://localhost:/websocket
中的/websocket
其余对应的方法,看下面例子即可
【前端】主要js
var websocket = null;
//判断当前浏览器是否支持WebSocket,是则创建WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:[port]/websocket");
}else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function () {
console.log("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function () {
console.log("WebSocket连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function (event) {
console.log(event.data);
}
//连接关闭的回调方法
websocket.onclose = function () {
console.log("WebSocket连接关闭");
}
//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
//如果websocket连接还没断开就关闭了窗口,后台server端会抛异常。
//所以增加监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接
window.onbeforeunload = function () {
closeWebSocket();
}
【后端】主要代码:
/**
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值[/websocket]即为客户端webSocket连接的url地址
*/
@ServerEndpoint("/websocket")
public class WebSocketTest {
/**
* 连接建立成功调用的方法
* @param session 客户端的连接会话
*/
@OnOpen
public void onOpen(Session session){
System.out.println("连接开始!");
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
System.out.println("连接关闭!");
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端的消息:" + message);
//发送消息回去
session.getBasicRemote().sendText(message);
//session.getAsyncRemote().sendText(message);
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}
}
相关工具
WebSocketd:开源的实时监控服务器
github地址: https://github.com/joewalnes/websocketd
概念
1、轮询:
客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。
- 优点:后端程序编写比较容易。
- 缺点:请求中有大半是无用,浪费带宽和服务器资源。
- 实例:适于小型应用。
2、长轮询:
客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
- 优点:在无消息的情况下不会频繁的请求,耗费资小。
- 缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。 Comet异步的ashx。
- 实例:WebQQ、Hi网页版、Facebook IM。
3、长连接:
在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
- 优点:消息即时到达,不发无用请求;管理起来也相对便。
- 缺点:服务器维护一个长连接会增加开销。
- 实例:Gmail聊天
4、Flash Socket:
在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
- 优点:实现真正的即时通信,而不是伪即时。
- 缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。
- 实例:网络互动游戏。
5、Websocket:
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
- 特点:
- 事件驱动
- 异步
- 使用ws或者wss协议的客户端socket
- 能够实现真正意义上的推送功能
- 缺点:少部分浏览器不支持,浏览器支持的程度与方式有区别。