WebSocket的备用方案SockJS
WebSoket是一个相对比较新的规范,虽然它早在2011年底将就实现了规范化,但即便如此,在web浏览器和应用服务器上依然没有得到一致的支持。WebSocket是一项非常棒的技术,但是如果由于web浏览器或应用服务器不支持导致我们无法使用的话,是一件非常遗憾的事情。有幸的是,我们有备用方案,他就是SockJS。
SockJS是WebSocket技术的一种模拟,在表面上它将尽可能对应WebSocket API,但是在底层它非常智能,如果WebSocket技术不可用的话,就会选择另外的通信方式。SockJS会优先选用WebSocket,但是如果WebSocket不可用的话,他将会从如下的方案中挑选最优的可行方案:
- XHR流
- XDR流
- iFrame事件源
- iFrame HTML文件
- XHR轮询
- XDR轮询
- iFrame XHR轮询
- JSONP轮询
本示例基于创建 WebSocket 服务进行。
1. 在服务器端启用SockJS通信
addHandler方法返回WebSocketHandlerRegistry,通过简单的调用其withSockJS()方法级就能声明我们要使用SockJS功能,如果WebSocket不可用的话,SockJS的备选方案就会发生作用。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(marcoHandler(), "/marco").withSockJS();
}
@Bean
public MarcoHandler marcoHandler() {
return new MarcoHandler();
}
}
2. 服务器端使用WebJars解析Web资源
2.1 pom配置增加sockjs依赖
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
2.2 增加resource handler
package com.tm.sbia.feature.websocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
3. 客户端代码调整
引入sockjs
<script src="webjars/sockjs-client/1.0.2/sockjs.min.js"></script>
wsUri协议由ws改为http
websocket改为SockJS对象
<script language="javascript" type="text/javascript">
var wsUri = "http://" + window.location.host + "/marco";
var output;
var count = 0;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new SockJS(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
...
</script>
4. 运行比对
Request URL is different.
Message format is different
参考
SpringBoot | 第十八章:web应用开发之WebJars使用
https://www.webjars.org/