Spring MVC的WebSocket使用

Spring MVC的WebSocket使用


JAVA后端开发知识总结(持续更新…)



一、WebSocket概述

1.1 建立WebSocket基本流程

  WebSocket协议(RFC 6455)是HTML5开始提供的一种标准化方法,可通过单个TCP连接在客户端和服务器之间建立全双工双向通信通道,实现长连接,它是与HTTP不同的TCP协议。WebSocket协议允许服务端主动向客户端推送数据。

  WebSocket交互始于一个HTTP请求,该请求使用HTTP Upgrade请求头进行升级,或在这种情况下切换到WebSocket协议:
请求报文
  UpgradeConnection用于声明自身发起的是WebSocket协议;Sec-WebSocket-Key是浏览器随机生成的,用于验证服务器; Sec-WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。

  而具有WebSocket支持的服务器代替通常的200状态代码,返回类似于以下内容的响应,表示已经接受到请求,成功建立了WebSocket:
响应报文
  成功握手后,HTTP升级请求的基础TCP套接字将保持打开状态,客户端和服务器均可继续发送和接收消息。

建立WebSocket连接流程

1.2 WebSocket和HTTP的区别

  在HTTP和REST中,应用程序被建模为许多URL。为了与应用程序交互,采用请求-响应方式,服务器根据HTTP URL、方法和请求头将请求路由到适当的处理程序。而且HTTP通信只能由客户端发起,是无状态无连接的。

  这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦,只能使用轮询或长轮询。但是它们效率低,非常浪费资源(因为必须不停连接,或者HTTP连接始终打开)。

  相比之下,在WebSocket中,通常只有一个URL用于初始连接,随后,所有应用程序消息都在同一TCP连接上流动。这指向了一种完全不同的异步的、事件驱动的消息传递体系结构。它的最大特点是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息

  WebSocket客户端和服务器可以通过HTTP握手请求上的Sec-WebSocket-Protocol请求头,协商使用更高级别的消息传递协议(如STOMP)。

WebSocket和HTTP的区别

注意
  WebSocket URL使用了ws://协议标识符,表明这是一个基本的WebSocket连接,如果是安全WebSocket的话,协议标识符将会变为wss://

二、Spring的WebSocket使用

2.1 WebSocket API

  Spring框架提供了一个WebSocket API,可用于编写处理WebSocket消息的客户端和服务器端应用程序。具体的文档可以在Spring官网查看。

2.1.1 WebSocketHandler

  为了在Spring使用相应的API来处理消息,实现对WebSocket的连接回调及消息发送的操作,必须编写一个继承WebSocketHandler的类,或者使用扩展的TextWebSocketHandler或BinaryWebSocketHandler。

  TextWebSocketHandler是AbstractWebSocketHandler(抽象类)的子类,它会拒绝处理二进制消息。它重载了handleBinaryMessage()方法,如果收到二进制消息,将会关闭WebSocket连接。其中,对于几个重要的方法,需要进行自定义实现:

  • afterConnectionEstablished:建立连接后触发的回调;
  • afterConnectionClosed:断开连接后触发的回调;
  • handleTextMessage:收到客户端消息时触发的回调;
  • handleTransportError:传输消息出错时触发的回调。
2.1.2 HandshakeInterceptor 和 WebSocketConfigurer

  定制初始HTTP WebSocket握手请求的最简单方法就是通过HandshakeInterceptor,它提供了“握手之前”和“握手之后”要进行的方法:

  • beforeHandshake:可以在握手升级之前进行一些操作,比如将连接的用户信息进行保存等;
  • afterHandshake:握手升级之后的处理。

  配置类实现WebSocketConfigurer接口,可以选择使用内置的拦截器将HTTP会话属性传递到WebSocket会话,也可以使用实现了HandshakeInterceptor接口的自定义拦截器:

  • addHandler:添加Handler处理器;
  • addInterceptors:添加拦截器。
2.1.3 设置跨域请求——setAllowedOrigins

  从Spring Framework 4.1.5开始,WebSocket和SockJS的默认行为是仅接受起源相同的请求,此检查主要用于浏览器客户端,三种可能的行为是:

  • 仅允许相同来源的请求(Allow only same-origin requests):此模式是默认情况,启用此模式时,不支持IE6和IE7。
  • 允许指定来源列表(Allow a specified list of origins):每个允许的来源必须以http://或https://开头。在此模式下,启用SockJS时,将禁用IFrame传输。因此,启用此模式时,不支持IE6到IE9。
  • 允许所有来源(Allow a specified list of origins)进行跨域设置,要启用此模式,应提供 * 作为允许值,在这种模式下,所有传输都可用。

  setAllowedOrigins方法在WebSocketConfigurer进行注册时就可以调用使用。

2.1.4 SockJS支持——withSockJS

  WebSocket是一个相对比较新的规范,在公共Internet上,控件之外的限制性代理可能会阻止WebSocket交互,所以需要一种WebSocket备选方案,解决此问题的方法是WebSocket仿真。

  SockJS是WebSocket技术的一种模拟,在表面上,它尽可能对应WebSocket API,但是在底层非常智能。如果WebSocket技术不可用的话,就会选择另外的通信方式。SockJS的目标是让应用程序使用WebSocket API,但在运行的过程中,在必要时使用非WebSocket替代方案,而无需更改应用程序代码。

  withSockJS方法在WebSocketConfigurer进行注册时就可以调用使用,应对浏览器不支持WebSocket协议的时候降级为轮询处理。

2.2 WebSocket在项目中的使用

  项目内容:客户端登陆之后,Vue加载页面时创建WebSocket连接,此时,Spring MVC拦截器拦截到WebSocket请求,保存用户信息,建立连接,同时调用SpringWebSocketHandler中重写的相应的回调方法。
项目

第一步:继承HttpSessionHandshakeInterceptor编写自定义拦截器

从前端发来的请求中的name参数获取登录者信息,并进行保存

public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor {
   
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
   
        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
        //获取请求URL的参数name的值</
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Spring MVC中整合WebSocket并获取请求参数,可以按照以下步骤进行: 1. 添加Maven依赖 ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.2.3.RELEASE</version> </dependency> ``` 2. 配置WebSocketSpring MVC的配置类中添加WebSocket配置: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/websocket").setAllowedOrigins("*"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } ``` 其中,`MyHandler`是自定义的WebSocket处理器。 3. 实现WebSocket处理器 实现`WebSocketHandler`接口,并在`afterConnectionEstablished`方法中获取请求参数: ```java public class MyHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { Map<String, String> queryParams = getQueryParams(session); // 处理WebSocket连接建立后的逻辑 } private Map<String, String> getQueryParams(WebSocketSession session) { URI uri = session.getUri(); String query = uri.getQuery(); return parseQuery(query); } private Map<String, String> parseQuery(String query) { Map<String, String> queryParams = new HashMap<>(); if (query != null) { String[] parts = query.split("&"); for (String part : parts) { String[] keyValue = part.split("="); if (keyValue.length == 2) { String key = keyValue[0]; String value = keyValue[1]; queryParams.put(key, value); } } } return queryParams; } // 其他WebSocketHandler接口的实现 // ... } ``` 在`getQueryParams`方法中,通过`WebSocketSession`对象的`getUri`方法获取请求的URI,再通过`parseQuery`方法解析出参数。 4. 客户端发送请求 在客户端使用WebSocket发送请求时,可以在URL后面添加参数: ```javascript var socket = new WebSocket("ws://localhost:8080/websocket?param1=value1&param2=value2"); ``` 这样,在WebSocket连接建立后,`MyHandler`中的`afterConnectionEstablished`方法就能够获取到这些参数了。 以上就是在Spring MVC中整合WebSocket并获取请求参数的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值