spring-boot本身对websocket提供了很好的支持,可以直接原生支持sockjs和stomp协议。百度搜了一些中文文档,虽然也能实现websocket,但是并没有直接使用spring-boot直接支持的websocket的特性。

在实践中觉得stromp协议对于websocket开发的自由度影响比较大。这里给大家展示一种自由度比较大的方案。

主要就是三个组件,config,interceptor和handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
@EnableWebSocket
public class MessageWebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(messageWebSocketHandler(), "/sockjs/message")
.addInterceptors(new MessageWebSocketInterceptor()).withSockJS();
}
 
@Bean
public MessageWebSocketHandler messageWebSocketHandler() {
return new MessageWebSocketHandler();
}
}

config需要继承WebSocketConfigurer需要重写registerWebSocketHandlers方法,指明handler和interceptor。

interceptor顾名思义为拦截器我们可以在websocket建立之间和之后做一些事情。重载beforeHandshakeafterHandshake就OK。我在beforeHandshake这里还操作了attributes。被修改的attributes会被带到后面websocket的session之中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MessageWebSocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
String siteId = servletRequest.getServletRequest().getParameter("siteId");
String userId = servletRequest.getServletRequest().getParameter("userId");
if (siteId == null || userId == null) {
return false;
}
attributes.put("siteId", siteId);
attributes.put("userId", userId);
}
return true;
}
 
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
 
}
}

handler里面就可以写websocket的逻辑啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class MessageWebSocketHandler implements WebSocketHandler {
 
@Override
public void afterConnectionEstablished(WebSocketSession session) {
 
}
 
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
 
}
 
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
}
 
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
 
}
 
@Override
public boolean supportsPartialMessages() {
return false;
}
}

spring-boot单元测试可以写websocket-client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebsocketTest {
private final Logger logger = LoggerFactory.getLogger(WebsocketTest.class);
private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Throwable> failure = new AtomicReference<>();
@LocalServerPort
private int port;
private SockJsClient sockJsClient;
 
@Before
public void setup() {
List<Transport> transports = new ArrayList<>();
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
transports.add(new RestTemplateXhrTransport());
this.sockJsClient = new SockJsClient(transports);
}
 
@Test
public void getGreeting() throws Exception {
 
this.sockJsClient.doHandshake(new TestWebSocketHandler(failure),
"ws://localhost:"+String.valueOf(port)+"/sockjs/message?siteId=webtrn&userId=lucy");
if (latch.await(60, TimeUnit.SECONDS)) {
if (failure.get() != null) {
throw new AssertionError("", failure.get());
}
}
else {
fail("Greeting not received");
}
 
}
 
 
 
private class TestWebSocketHandler implements WebSocketHandler {
 
private final AtomicReference<Throwable> failure;
 
TestWebSocketHandler() {
this.failure = null;
}
 
;
 
TestWebSocketHandler(AtomicReference<Throwable> failure) {
this.failure = failure;
}
 
;
 
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.info("client connection established");
session.sendMessage(new TextMessage("hello websocket server!"));
}
 
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String payload = (String) message.getPayload();
logger.info("client handle message: " + payload);
if (payload.equals("hello websocket client! webtrn lucy")) {
latch.countDown();
}
 
if (payload.equals("web socket notify")) {
latch.countDown();
}
}
 
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
logger.info("client transport error");
}
 
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
logger.info("client connection closed");
}
 
@Override
public boolean supportsPartialMessages() {
return false;
}
}
 
}

如果采用stomp协议的话可以参考spring-boot的一个ws-guide。有问题还是直接看spring文档比较好。

spring-boot支持websocket的更多相关文章

  1. spring boot 集成 websocket 实现消息主动推送

    spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...

  2. Spring Boot 集成 WebSocket 实现服务端推送消息到客户端

    假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...

  3. Spring Boot之WebSocket

    一.项目说明 1.项目地址:https://github.com/hqzmss/test01-springboot-websocket.git 2.IDE:IntelliJ IDEA 2018.1.1 ...

  4. spring boot: 支持jsp,支持freemarker

    spring boot: 支持jsp,支持freemarker 支持jsp: 加入依赖 <!--jsp--> <dependency> <groupId>org.a ...

  5. Spring Boot 支持多种外部配置方式

    Spring Boot 支持多种外部配置方式 http://blog.csdn.net/isea533/article/details/50281151 这些方式优先级如下: 命令行参数 来自java ...

  6. 【websocket】spring boot 集成 websocket 的四种方式

    集成 websocket 的四种方案 1. 原生注解 pom.xml <dependency> <groupId>org.springframework.boot</gr ...

  7. Spring Boot 支持 HTTPS 如此简单,So easy!

    这里讲的是 Spring Boot 内嵌式 Server 打 jar 包运行的方式,打 WAR 包部署的就不存在要 Spring Boot 支持 HTTPS 了,需要去外部对应的 Server 配置. ...

  8. Spring Boot 支持 HTTPS 如此简单,So easy!

    这里讲的是 Spring Boot 内嵌式 Server 打 jar 包运行的方式,打 WAR 包部署的就不存在要 Spring Boot 支持 HTTPS 了,需要去外部对应的 Server 配置. ...

  9. spring boot整合websocket

    转载自:https://www.cnblogs.com/GoodHelper/p/7078381.html 一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日 ...

  10. Spring Boot 系列 - WebSocket 简单使用

    在实现消息推送的项目中往往需要WebSocket,以下简单讲解在Spring boot 中使用 WebSocket. 1.pom.xml 中引入 spring-boot-starter-websock ...

随机推荐

  1. BIND的安装配置

    简介 bind是dns协议的一种实现,也就是说,bind仅仅是实现DNS协议的一种应用程序 bind运行后的进程名叫named,不叫bind bind bind的配置文件在:/etc/named.co ...

  2. 3dContactPointAnnotationTool开发日志(三一)

      在玩的时候遇到了一个python的问题: Traceback (most recent call last): File ".\convert.py", line 13, in ...

  3. vue-cli配置axios,并基于axios进行后台请求函数封装

    文章https://www.cnblogs.com/XHappyness/p/7677153.html已经对axios配置进行了说明,后台请求时可直接this.$axios直接进行.这里的缺点是后端请 ...

  4. CDN加速-内容分发网络

    内容分发网络 (互联网技术) 编辑 CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输 ...

  5. Spring事务管理Transaction【转】

    Spring提供了许多内置事务管理器实现(原文链接:https://www.cnblogs.com/qiqiweige/p/5000086.html): DataSourceTransactionMa ...

  6. 【vim】vim常用命令

    移动: h 或 向左箭头键(←)  #光标向左移劢一个字符 j 或 下箭头键(↓)    #光标向下移劢一个字符 k 或 向上箭头键(↑)    #光标向上移劢一个字符 l 或 向右箭头键(→)    ...

  7. 在js和C#中split应用和去除字符串分组后的空值

    如字符串 string answer="A,B,D,",在 js和 C#按","分成数组 js: , useranswer.length - ).split(& ...

  8. Javascript中判断变量是数组还是对象(array还是object)

    怎样判断一个JavaScript变量是array还是obiect? 答案: 1.如果你只是用typeof来检查该变量,不论是array还是object,都将返回‘objec'. 此问题的一个可行的答案 ...

  9. bzoj4569-萌萌哒

    题目 有一个长度为\(n\)的十进制数,用\(s\)表示.有\(m\)个限制条件,每个条件形如:\((l_1,r_1,l_2,r_2)\),表示\(s[l_1:r_1]=s[l_2:r_2]\). 现 ...

  10. 【JavaScript】JAVA-表格里的c:foreach使用及数字总计

    两步:1.上图 2.上代码 <div class="group-accordion" collapsible="true" active="tr ...