# 简介

WebSocket协议在2008年诞生,2011年成为国际标准,所有游览器都已经支持了。

最大的特点就是,服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息,是真正的实现双平等对话,属于服务器推送数据技术的一种。

  1. 节约带宽:不停的使用轮询服务端获取数据使用的是 http 协议,head 信息很大,有效数据占比低,而使用 webSocket 方式,head 信息很小,有效数据占比高
  2. 无浪费:轮询 10 次,可能前 9 次都是白浪费,因为前 9 次可能没有拿到新数据,而 WebSocket 是由服务器主动发起的,来的都是新数据
  3. 实时性:考虑到服务器压力,轮询的时间不能太长,否则服务器压力太大,所有轮询的时间都是间隔较长,比如 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发送消息

    }

}