2023-06-18 11:17

WebSocket详解

王姐姐

JavaEE

(552)

(0)

收藏

Websocket详解

WebSocket 是一种支持双向通讯网络通信协议。

意思就是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息

属于服务器推送技术的一种。

为什么需要 WebSocket?

了解计算机网络协议的人,应该都知道:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步 JavaScript 和 XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态。这相比于轮询方式的不停建立连接显然效率要大大提高。

spring Boot整合websocket

第一步:导入依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

第二步:编写WebSocketConfig配置类

@Configuration
public class WebSocketConfig{
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}


第三步:编写WebSocket类

//注册成组件
@Component
//定义websocket服务器端,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址
@ServerEndpoint("/websocket")
//如果不想每次都写private  final Logger logger = LoggerFactory.getLogger(当前类名.class); 可以用注解@Slf4j;可以直接调用log.info
@Slf4j
public class WebSocket {
 
    //实例一个session,这个session是websocket的session
    private Session session;
 
    //存放websocket的集合(本次demo不会用到,聊天室的demo会用到)
    private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
 
    //前端请求时一个websocket时
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);
        log.info("【websocket消息】有新的连接, 总数:{}", webSocketSet.size());
    }
 
    //前端关闭时一个websocket时
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        log.info("【websocket消息】连接断开, 总数:{}", webSocketSet.size());
    }
 
    //前端向后端发送消息
    @OnMessage
    public void onMessage(String message) {
        log.info("【websocket消息】收到客户端发来的消息:{}", message);
    }
 
    //新增一个方法用于主动向客户端发送消息
    public static void sendMessage(String message) {
        for (WebSocket webSocket: webSocketSet) {
            log.info("【websocket消息】广播消息, message={}", message);
            try {
                webSocket.session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

第四步:改造控制器

编写一个接口方法,调用websocket的sendMessage方法

@Resourse
Private WebSocket webSocket;
public void sendMessage(String msg){
    webSocket.sendMessage(msg);
}


第五步:编写前端代码

<script type="text/javascript">
    var websocket = null;
 
    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8080/websocket");
    }else{
        alert('Not support websocket')
    }
 
    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("发生错误");
    };
 
    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("建立连接");
    }
 
    //接收到消息的回调方法
    websocket.onmessage = function(event){
console.log(event.data)
        // setMessageInnerHTML(event.data);
$(".progress-bar").attr("style","width:"+event.data+"%")
    }
 
    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("关闭连接");
    }
 
    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
alert("已关闭连接");
        websocket.close();
    }
 
    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }
 
    //关闭连接
    function closeWebSocket(){
alert("已关闭连接");
        websocket.close();
}
</script>

解释:

1、

var websocket = null;

 

    //判断当前浏览器是否支持WebSocket

  if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8089/websocket");
    }else{
        alert('Not support websocket')
    }

首先建立websocket连接。

注意:此处的地址的ws://是固定写法,后面加上你的ip+端口+WebSocket的ServerEndpoint注解配置的路径。

2、

//连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("发生错误");
    };
 
    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("建立连接");
    }
 
    //接收到消息的回调方法
    websocket.onmessage = function(event){
        console.log(event.data)
        // setMessageInnerHTML(event.data);
        $(".progress-bar").attr("style","width:"+event.data+"%")
    }
 
    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("关闭连接");
    }


都是websocket的固定写法,几个回调函数。

最后设置一个发送按钮请求控制器方法,到此整合完毕。


0条评论

点击登录参与评论