前言
一提到网络协议就不得不说我们每天都在用的HTTP协议。几乎所有我们访问的网站都是基于HTTP协议发送的。HTTPS相比HTTP,就是多了一个TSL加密,使用起来更安全,但其终究还是HTTP协议。而webSocket却是一个全新的网络协议。
一、webSocket协议是什么?
web => 浏览器
Socket => TCP连接
webSocket =>是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输。
二、webSocket与Http的区别
从消息上来说:
HTTP协议是单向传输,服务器端只有接收到客户端的请求后,才能做出响应,返还给客户端,更像是主动索取一样。
WebSocket协议是双向消息,在首次连接过后,服务器端与客户端之间,就没有什么本质上的区别了,大家都可以给对方发消息,也可以接收对方的消息,更像是聊天互动一样。
从连接上来说:
HTTP协议是短连接,一次响应完就立刻结束连接了,每次连接仅仅做一次功能业务的操作。
webSocket协议是长连接,一次连接过后,就会持续的发送数据包以保持连接,在这次连接过程中,只要某一方没有主动断开就可以一直发送请求,每次连接都可以持续性的做一些功能业务的操作。
三、webSocket的应用场景
因为webSocket的实时连接性,在很多长时间互动的页面就很需求,比如视频弹幕、网页聊天、股票实时更新等等就是用webSocket来实现的
四、webSocket的简单使用
1、要想使用webSocket,就需要先导依赖:
代码如下(示例)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、编写webSocket服务器类,用来和浏览器进行交互
代码如下(示例)
@Component
@ServerEndpoint("/ws")
public class WebSocketServer {
//存放会话对象
private static final List<Session> sessionList = new ArrayList<>();
//连接成功调用的方法
@OnOpen
public void onOpen(Session session){
System.out.println("有连接进来了");
sessionList.add(session);
}
//收到客户端消息后调用的方法
@OnMessage
public void onMessage(Session session ,String msg) throws IOException {
System.out.println("有消息进来了:"+msg);
session.getBasicRemote().sendText(msg);
}
//连接关闭调用的方法
@OnClose
public void onClose(){
System.out.println("连接断开了");
}
//给所有人发消息的方法
public void sendAll(String msg){
for (Session session : sessionList) {
try {
//浏览器给服务器端发送什么消息,由调用者决定
session.getBasicRemote().sendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、光有依赖和服务器类还不够,还得需要配置信息
代码如下(示例)
@Configuration
public class WebConfigure {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
4、我们搞一个静态页面测试一下
代码如下(示例)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Demo</title>
</head>
<body>
<input id="text" type="text" />
<button onclick="send()">发送消息</button>
<button onclick="closeWebSocket()">关闭连接</button>
<div id="message">
</div>
</body>
<script type="text/javascript">
var websocket = null;
var clientId = Math.random().toString(36).substr(2);
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
//连接WebSocket节点
websocket = new WebSocket("ws://localhost:8080/ws");
}
else{
alert('Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function(){
setMessageInnerHTML("error");
};
//连接成功建立的回调方法
websocket.onopen = function(){
setMessageInnerHTML("连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function(event){
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function(){
setMessageInnerHTML("close");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
websocket.close();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//发送消息
function send(){
var message = document.getElementById('text').value;
websocket.send(message);
}
//关闭连接
function closeWebSocket() {
websocket.close();
}
</script>
</html>
注意:
五、项目跑起来测试一下
额外补充:加了一个定时发送消息的方法,每隔两秒就会调用一次上面的sendAll方法
代码如下(示例)
@Component
public class MyTask{
@Autowired
private WebSocketServer webSocketServer;
@Scheduled(fixedDelay = 2000)
public void print(){
webSocketServer.sendAll("黄帅帅真帅");
}
}
直接上页面测试
未连接状态:
敲下回车:
服务器这边显示有连接进来了,浏览器这边显示连接成功
服务器每隔两秒就会发送一条消息:
当浏览器这边发送消息时:
测试成功~
总结
充电时刻
webSocket协议是一个全双工通信协议,可以做到浏览器与服务器之间,一次连接,长时间交流的效果。
但是万事万物都不是绝对完美,webSocket也有缺点:
- 服务器长期维护长连接需要一定的成本
- 各个浏览器支持程度不一
- WebSocket 是长连接,受网络限制比较大,需要处理好重连
所以,WebSocket并不能完全取代HTTP,它只适合在特定的场景下使用