# 简介
WebSocket协议在2008年诞生,2011年成为国际标准,所有游览器都已经支持了。
最大的特点就是,服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息,是真正的实现双平等对话,属于服务器推送数据技术的一种。
- 节约带宽:不停的使用轮询服务端获取数据使用的是 http 协议,head 信息很大,有效数据占比低,而使用 webSocket 方式,head 信息很小,有效数据占比高
- 无浪费:轮询 10 次,可能前 9 次都是白浪费,因为前 9 次可能没有拿到新数据,而 WebSocket 是由服务器主动发起的,来的都是新数据
- 实时性:考虑到服务器压力,轮询的时间不能太长,否则服务器压力太大,所有轮询的时间都是间隔较长,比如 10 多秒进行一次轮询,而使用 webSocket,数据都是服务器主动推过来的,实时性很高
其它特点有:
1. 建立在 TCP 协议之上,服务端实现比较容易。
2. 与 HTTP 协议有良好的兼容性,默认端口 80 和 443,并且握手阶段采用 HTTP 协议,因此不容易屏蔽,能通过各种 HTTP 代理服务器。
3. 数据格式比较轻量,性能开销较小,通信高效。
4. 可以发送二进制数据,也可以发送文本。
5. 没有同源限制,客户端可以与任意服务器通信。
6. 协议标识是:ws ,如果是加密,则为:wss ,服务器网址就是 URL。
JavaScript 客户端
const ws = new WebSocket('ws://127.0.0.1:8080/webSocketTest/ws/ucy')
ws.onopen = function (evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function (evt) {
console.log("Received Message: " + evt.data);
ws.close();
};
ws.onclose = function (evt) {
console.log("Connection closed.");
};
Java 服务端
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* @ClassName WebSocketEchoServer
* @Description TODO
* @Author JY
* @Date 2023/4/24
**/
@Component
@ServerEndpoint("/ws/{username}")
public class WebSocketEchoServer {
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
System.out.println("username = " + username + " is online.");
}
@OnClose
public void onClose(Session session, @PathParam("username") String username, CloseReason closeReason) {
System.out.println("username = " + username + " is offline.");
System.out.println("Closing a WebSocket due to " + closeReason.getReasonPhrase());
}
// @OnMessage
// public String onMessage(String message, Session session) throws IOException {
// System.out.println("received message=" + message);
// return "echo " + message;
// }
@OnMessage
public void onMessage(String message, Session session) throws IOException {
System.out.println("received message=" + message);
session.getBasicRemote().sendText("echo " + message);
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("发生错误");
throwable.printStackTrace();
}
public void boardCast(Message message) {
// todo: 遍历所有的session,给所有session发送消息
}
}