使用SpringBoot搭建实时通信服务

在软件开发过程中,经常需要获取服务器端数据来展示给用户,对于数据的及时性有要求的场景,我们可能会采用长轮询等方式,来以一定的频率向服务器发起请求拉取数据,轮询方式会持续占用系统资源,效率较低,那么有没有一种解决方案,能做到服务器端有数据更新,及时通知客户端呢?通过使用websocket技术,我们可以做到客户端与服务器端的全双工通信,两端都可以实时的发送数据给对方~,下面就给大家介绍下SpringBoot中怎么整合websocket技术

  • SpringBoot版本 2.4.5

使用方式

1.修改SpringBoot工程中的pom.xml配置,增加websocket的依赖

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

2.修改SpringBoot工程启动类,添加@EnableWebSocket注解来启用websocket能力支持

3.添加websocket配置
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/config/SpringWebSocketConfig.java

**@Configuration
public class SpringWebSocketConfig implements WebSocketConfigurer {

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//添加通信地址路径
registry.addHandler(buildTextHandler(), "/ws").setAllowedOrigins("*");
}

@Bean
public WebSocketHandler buildTextHandler() {
//添加消息处理器
return new TextHandler();
}

}**

4.实现自己的消息处理器
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/websocket/handler/TextHandler.java

**@Slf4j
public class TextHandler extends TextWebSocketHandler {

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
if (session.isOpen()) {
log.info("receive websocket message:{} session:{}", message, session.getId());
TextMessage returnMessage = new TextMessage(message.getPayload() + " received at server");
session.sendMessage(returnMessage);
}
}

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
//建立连接后保存WebSocketSession会话
SessionManager.put(session.getId(), session);
log.info("session[{}] afterConnectionEstablished", session.getId());
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.info("session[{}] afterConnectionClosed", session.getId());
//释放连接后移除WebSocketSession会话
SessionManager.remove(session.getId());
}
}**

5.建立Controller控制器层映射方法,来测试主动推送消息到客户端
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/controller/WebsocketController.java

**@RestController
@RequestMapping("/ws")
public class WebsocketController {

@GetMapping("{session}/send")
public void send(@PathVariable("session") String session, String msg) {
WebSocketMessage webSocketMessage = new TextMessage(msg);
try {
SessionManager.get(session).sendMessage(webSocketMessage);
} catch (IOException e) {
e.printStackTrace();
}
}

}**

6.编写客户端html代码验证websocket能力
完整代码参考:https://github.com/netbuffer/UItest/blob/master/websocket/index.html)

**<script type="text/javascript">
var ws = new WebSocket("ws://localhost:17000/ws");
ws.onopen = function () {
console.log("Connection open ...");
};
ws.onmessage = function (r) {
console.log("Received Message: " + r.data);
};
ws.onclose = function () {
console.log("Connection closed.");
};
</script>
<input name="text" placeholder="请输入文本内容" /><button onclick="ws.send(document.querySelector('input[name=\'text\']').value)">send</button> <button onclick="ws.close()">close</button>**

运行效果

启动SpringBoot工程,再使用chrome浏览器访问客户端页面,打开开发者工具

观察开发者工具控制台已经打印出连接的日志,服务器端控制台也已经打印出连接日志
现在通过客户端页面发送一些消息,来查看服务器端日志是否有输出~

观察结果可以看到服务器端已经收到对应内容,并写回响应消息给客户端了

再测试下服务器主动推送消息给客户端的效果,使用Postman工具访问我们编写的接口来发送一些消息给客户端,注意session字符串可以从服务器日志打印中找到

**GET /ws/73f67e83-79f5-a238-844f-c80f6926a429/send?msg=你好 HTTP/1.1
Host: localhost:17000**

观察结果可以看到服务器已经能实时推送相应的内容给客户端了~

完整测试工程参考:https://github.com/netbuffer/spring-boot-websocket-demo)

举报/反馈


原网址: 访问
创建于: 2023-04-10 09:58:04
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论