下面我将详细讲解“spring WebSocket示例详解”的完整攻略。
简介
本文将详细介绍如何在 Spring 框架下使用 WebSocket。WebSocket 是一种实时通信协议,能够从客户端向服务器端推送消息,而服务器端能够主动向客户端推送消息。相比于传统的 HTTP 请求方式,WebSocket 具有实时性更强、资源占用更少等优点。
本文使用 Spring Boot 2.x,同时也会使用到 Spring Framework 中的 Spring WebSocket。
环境准备
要运行本文的示例代码,需要具备以下环境:
- JDK 1.8 或以上;
- Maven 3.2 或以上;
- Idea 或 Eclipse 等 IDE。
项目搭建
首先,我们需要搭建一个 Spring Boot 的基础项目。可以使用 Spring Initializr 快速创建一个基础的 Spring Boot 项目。
然后,我们需要添加 Spring WebSocket 的依赖。在 pom.xml 中添加以下代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
示例一:简单示例
本示例演示了如何在 Spring Boot 应用中实现 WebSocket 的基本功能。
- 创建一个 WebSocketConfig 类,配置消息代理和消息端点:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket-demo").withSockJS();
}
}
- 创建一个控制器来处理 WebSocket 相关的请求:
@Controller
public class WebSocketController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) {
return new Greeting("Hello, " + message.getName() + "!");
}
}
- 创建一个 HelloMessage 类和一个 Greeting 类,用于传递消息:
public class HelloMessage {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Greeting {
private String content;
public Greeting(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
- 最后,我们需要创建一个前端页面来测试 WebSocket。以下是一个基本的 HTML 页面:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Demo</title>
<script src="/webjars/sockjs-client/1.0.2/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/2.3.3/stomp.min.js"></script>
<script src="/js/app.js"></script>
</head>
<body>
<div>
<label for="name">Name:</label> <input type="text" id="name">
<button id="connect">Connect</button>
<button id="disconnect">Disconnect</button>
</div>
<div id="greetings">
</div>
</body>
</html>
app.js 的代码如下:
var stompClient = null;
function connect() {
var socket = new SockJS('/websocket-demo');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}
function showGreeting(message) {
$("#greetings").append("<tr><td>" + message + "</td></tr>");
}
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#greetings").show();
}
else {
$("#greetings").hide();
}
}
$(function () {
$("form").on('submit', function (e) {
e.preventDefault();
});
$("#connect").click(function () {
connect();
});
$("#disconnect").click(function () {
disconnect();
});
$("#send").click(function () {
sendName();
});
});
运行项目,访问 http://localhost:8080/index.html,测试 WebSocket 是否可用。
示例二:群聊示例
本示例演示了如何在 Spring Boot 应用中实现 WebSocket 群聊的功能。
- 创建一个 ChatRoom 类,该类保存了 WebSocket 会话的管理器和一个群聊列表:
@Component
public class ChatRoom {
private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
private final List<String> messages = new CopyOnWriteArrayList<>();
public void addSession(WebSocketSession session) {
sessions.put(session.getId(), session);
}
public void removeSession(WebSocketSession session) {
sessions.remove(session.getId());
}
public List<String> getMessages() {
return messages;
}
public void addMessage(String message) {
messages.add(message);
if (messages.size() > 100) {
messages.remove(0);
}
}
public void broadcast(String message) {
TextMessage textMessage = new TextMessage(message);
sessions.values().forEach(session -> {
try {
session.sendMessage(textMessage);
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
- 创建一个 WebSocketHandler 类,用于处理 WebSocket 相关的请求:
@Component
public class WebSocketHandler extends TextWebSocketHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private ChatRoom chatRoom;
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
ChatMessage chatMessage = objectMapper.readValue(message.getPayload(), ChatMessage.class);
chatRoom.addMessage(chatMessage.getFrom() + ": " + chatMessage.getMessage());
chatRoom.broadcast(chatMessage.getFrom() + ": " + chatMessage.getMessage());
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
chatRoom.addSession(session);
for (String message : chatRoom.getMessages()) {
session.sendMessage(new TextMessage(message));
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
chatRoom.removeSession(session);
}
}
- 创建一个 ChatMessage 类,用于传递消息:
public class ChatMessage {
private String from;
private String message;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
- 创建一个控制器,用于处理页面请求:
@Controller
public class PageController {
@RequestMapping("/")
public String index() {
return "index";
}
}
- 创建一个前端页面来测试 WebSocket。以下是一个基本的 HTML 页面:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Chat Demo</title>
</head>
<body>
<form onsubmit="return false;">
Name: <input type="text" id="name" value="User1"><br>
Message: <input type="text" id="message"><br>
<button onclick="sendMessage()">Send</button>
</form>
<hr>
<div id="chat">
</div>
<script type="text/javascript">
var ws;
document.addEventListener("DOMContentLoaded", function(event) {
ws = new WebSocket("ws://" + document.location.host + "/ws");
ws.onmessage = showMessage;
ws.onclose = console.warn;
});
function showMessage(event) {
var data = JSON.parse(event.data);
var chat = document.getElementById("chat");
var message = document.createElement("p");
message.innerText = data;
chat.append(message);
}
function sendMessage() {
var name = document.getElementById("name").value;
var message = document.getElementById("message").value;
var chatMessage = {from: name, message: message};
ws.send(JSON.stringify(chatMessage));
document.getElementById("message").value = "";
}
</script>
</body>
</html>
以上就是使用 Spring WebSocket 的基本流程,如有问题请随时提问。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring WebSocket示例详解 - Python技术站