😃 WebSocket 与 Spring

** 本案例所用软件和框架版本 **

Tomcat: 8.5.50

Spring: 5.1.5.RELEASE

Socket.js: v1.5.0

1. 什么是WebSocket?

WebSocket可以实现客户端(浏览器)与服务器之间的全双工通信。对于一些需要保持浏览器和服务器之间连续通信的业务会有很大的帮助,相比于使用Ajax轮询访问服务器的方法。

2. 客户端WebSocket JS库 socket.js

这里我选择使用socket.js库作为操作websocket的方式。具体使用案例如下:

	    //括号中为服务端设置暴露的地址。(实际设置格式为"/项目名/暴露的URL")
	    var sock = new SockJS("/sixin"); 
	    //当连接建立时调用的函数
            sock.onopen = function() {
                console.log('已连接打开');
            };

            //收到服务器端发送的消息时调用。
            sock.onmessage = function(e) {
                var msg = e.data;
                console.log("msg:"+msg);
            };

	    //socket连接关闭时调用的方法
            sock.onclose = function() {
                console.log('连接已关闭');
            };

	    //下面两个函数是确保客户端关闭,但没有及时断开socket连接(可能导致服务端出现异常)
            //当关闭窗口时调用执行的函数
            window.onbeforeunload = function () {
                sock.close();
            }

            //当页面刷新时调用执行的函数
            window.onunload = function () {
                sock.close();
            }

当socket连接建立后,服务端会为每一个连接维持一个SocketSession , 以此来区分每个连接,并通过这个session向指定的客户端发送消息

因此,对于每个session来说,都有一个sessionID。我们这里使用的第三方JS WebSocket库,它的sessionID如果没有自己指定的话,默认会是一个随机的6位字符。而原生的WebSocket则是数字作为ID,而且是顺序的。

至此,客户端已经搭建完毕,其已经具备了和服务端进行全双工通信的能力

3. Spring整合WebSocket

3.1 导包

	<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>

3.2 编写处理客户端请求的“特定的" Handler

在前面编写客户端 WebSocket的时候,我们设置了一个请求的路径,结尾有个类似于SpringMVC Controller请求路径的东西,但是它并不是Controller,我们不需要为其设置一个Controller方法,但是这里我们定义的这个Handler其宏观上的执行和SpringMVC 的Controller是有些类似的,都需要定义处理的方法,然后设置一个请求路径。

继承 TextWebSocketHandler

代码摘自Spring官方文档: spring

import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;

public class MyHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        //当收到客户端消息时调用的方法
        //session: 标识客户端的session。其id可通过session.getId()获得
        //message: 客户端发送的信息,可转化为字符串 messaget.getPayload().toString()
        
        //可以调用session发送信息的方法为指定的客户端发送消息。
        session.sendMessage(new TextMessage("要发送的信息"));
    }
    
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        //当与客户端的连接建立时调用的方法,可以在这里把session保存起来。
    }
    
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
       //当客户端的连接关闭时调用的方法
    }

}

3.3 在Spring配置文件中加入映射(请求路径和Handler之间的映射)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        https://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <!--定义请求与Handler之间的映射-->
    <!--path为请求路径,前端请求时用;handler指向我们定义的HandlerBean-->
    <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler"/>
        <websocket:sockjs/>
    </websocket:handlers>

    <!--前面我们编写的WebSocoetHandler-->
    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

至此,WebSocket搭建完毕

这篇博客的本意是帮助本人记录和记忆,同时在此基础上尽可能让别人能够看懂,如果对你有帮助我会很开心,如果未能,请查阅其他更全面的文章。 2020年12月27日20:04:55

posted @ 2020-12-27 20:10  小桃无主花自开  阅读(136)  评论(0编辑  收藏  举报