springboot1.x整合websocket实现广播式入门
程序员文章站
2022-05-21 21:25:56
...
这几天学习websocket,跟着书本学习一下广播式通信。
我使用的是idea,项目目录如下:
依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-websocket-2</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<!--servlet支持开启-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
springboot启动类什么的简单的就不贴出来丢人了。直接上配置类。
package com.shengxi.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
/**
* 开启使用STOMP,用来传输基于代理的消息,此时控制器支持使用
* 启用@messageMapping 就像使用 @RequestMapping 一样
*
* @author yan
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
/**
* 注册STOMP 协议的节点(endpoint) 并映射到指定的URL
* 注册一个 STOMP 的 endpoint ,并指定使用 SockJS协议
*
* @param registry 注册器
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/endpointLeung").withSockJS();
}
/**
* 配置消息代理
*广播式应配置一个 /topic 的消息代理
* @param registry
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
}
}
然后是进行信息交互的两个实体类。这里要注意,我是使用了lombok插件的。
package com.shengxi.entity;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author yan
* 浏览器提交数据实体类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WiselyMessage implements Serializable {
private String name;
}
package com.shengxi.entity;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @author yan
* 推送类
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class WiselyResponse implements Serializable {
private String responseMsg;
}
配置一个Controller进行交互。
package com.shengxi.web;
import com.shengxi.entity.WiselyMessage;
import com.shengxi.entity.WiselyResponse;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author yan
* 快速访问方案
*/
@Controller
public class WsController {
/**
* #@aaa@qq.com类似
* 监听 welcome路径
* 向/topic/getResponse发送消息
*
* @param message 客户端发回来的信息
* @return 因为是广播式测试,所以直接返回加工后的信息
* @throws InterruptedException ex
*/
@MessageMapping("/welcome")
@SendTo("/topic/getResponse")
public WiselyResponse say(WiselyMessage message) throws InterruptedException {
//暂停一下,模仿网络延时
Thread.sleep(3000);
return new WiselyResponse("Welcome, " + message.getName() + "!");
}
@GetMapping("/ws")
public String index() {
return "/ws";
}
}
最后来一个html进行交互。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Spring Boot+WebSocket+广播式</title>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
<div>
<div>
<button id="connect" onclick="connect();">连接</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
</div>
<div id="conversationDiv">
<label>输入你的名字</label><input type="text" id="name"/>
<button id="sendName" onclick="sendName();">发送</button>
<p id="response"></p>
</div>
</div>
<!--会自动导入 src/main/resources/static 下的静态资源-->
<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>
<script type="text/javascript">
var stompClient = null;
//设置是否连接
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
$('#response').html();
}
//自定义一个方法,在里面实现连接逻辑
function connect() {
//连接SockJS的endpoint
//连哪个节点?传入参数确定(是在WebSocketConfig中定义的节点)
var socket = new SockJS('/endpointLeung');
//使用STOMP子协议的WebSocket客户端
stompClient = Stomp.over(socket);
//连接WebSocket服务端
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
//通过stompClient.subscribe 订阅 /topic/getResponse (目标) 发送的消息
//这个是在控制器的 @SendTo 中定义的
stompClient.subscribe('/topic/getResponse', function (respnose) {
showResponse(JSON.parse(respnose.body).responseMessage);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
var name = $('#name').val();
//通过stompClient.send 向 /welcome (目标) 发送消息,
// 这个是在控制器的 @MessageMapping中定义的
stompClient.send("/welcome", {}, JSON.stringify({'name': name}));
}
function showResponse(message) {
var response = $("#response");
response.html(message);
}
</script>
</body>
</html>
问题:注意js的引用问题。jq如果有数字版本号,可能会引用失败。
源码在本人github。https://github.com/matthew9811/springbootlearn/tree/master/springboot-websocket-2
上一篇: WebSocket,实现简单的广播功能