Spring WebSocket 教程展示了如何在 Spring Web 应用中使用 WebSocket。
Spring 是用于创建企业应用的流行 Java 应用框架。
WebSocket
WebSocket 是一种计算机通信协议,可通过单个 TCP 连接提供全双工通信通道。 WebSocket 用于高度互动的应用,例如游戏,聊天或股票市场。
TextWebSocketHandler
Spring 使用WebSocketHandler
处理 WebSocket 消息和生命周期事件。 TextWebSocketHandler
是用于处理文本消息的WebSocketHandler
实现。
Spring TextWebSocketHandler
示例
以下应用使用TextWebSocketHandler
通过 WebSocket 处理文本消息。
web.xml
src
├───main
│ ├───java
│ │ └───com
│ │ └───zetcode
│ │ ├───config
│ │ │ MyWebInitializer.java
│ │ │ WebConfig.java
│ │ │ WebSocketConfig.java
│ │ └───handler
│ │ MyWebSocketHandler.java
│ ├───resources
│ └───webapp
│ │ index.html
│ └───WEB-INF
└───test
└───java
这是项目结构。
pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>textwebsocketex</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
</plugins>
</build>
</project>
在pom.xml
文件中,我们具有以下依存关系:spring-webmvc
,javax.servlet-api
和spring-websocket
。
com/zetcode/config/MyWebInitializer.java
package com.zetcode.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class, WebSocketConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
MyWebInitializer
初始化 Spring Web 应用。 它提供了两个配置类:WebConfig
和WebSocket
。
com/zetcode/config/WebConfig.java
package com.zetcode.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
@ComponentScan("com.zetcode")
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
WebConfig
配置DefaultServlet
。 在我们的应用中,我们有一个静态的index.html
页面,该页面由DefaultServlet
处理。
com/zetcode/config/WebSocketConfig.java
package com.zetcode.config;
import com.zetcode.handler.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private MyWebSocketHandler myWebSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myWebSocketHandler, "/socketHandler");
}
}
WebSocketConfig
使用@EnableWebSocket
在 Spring Web 应用中配置 WebSocket。
@Autowired
private MyWebSocketHandler myWebSocketHandler;
我们注入MyWebSocketHandler
。 已在registerWebSocketHandlers()
中注册。
com/zetcode/config/MyWebSocketHandler.java
package com.zetcode.handler;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.time.LocalTime;
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
var clientMessage = message.getPayload();
if (clientMessage.startsWith("hello") || clientMessage.startsWith("greet")) {
session.sendMessage(new TextMessage("Hello there!"));
} else if (clientMessage.startsWith("time")) {
var currentTime = LocalTime.now();
session.sendMessage(new TextMessage(currentTime.toString()));
} else {
session.sendMessage(new TextMessage("Unknown command"));
}
}
}
在MyWebSocketHandler
中,我们对套接字消息做出反应。
var clientMessage = message.getPayload();
通过getPayLoad()
方法,我们获得了客户端消息。
if (clientMessage.startsWith("hello") || clientMessage.startsWith("greet")) {
session.sendMessage(new TextMessage("Hello there!"));
} else if (clientMessage.startsWith("time")) {
var currentTime = LocalTime.now();
session.sendMessage(new TextMessage(currentTime.toString()));
} else {
session.sendMessage(new TextMessage("Unknown command"));
}
根据消息,我们将TextMessage
发送回客户端。
webapp/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home page</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"
rel="stylesheet">
</head>
<body>
<div class="ui container">
<h1>Spring MVC 5 WebSocket</h1>
<div class="two column grid">
<div class="row">
<div class="column">
<label for="myMessage">Message</label>
</div>
<div class="column">
<div class="ui input">
<input type="text" id="myMessage">
</div>
</div>
</div>
<div class="row">
<div class="column">
<label for="output">Response from Server</label>
</div>
<div class="column">
<textarea rows="8" cols="50" id="output" readonly="readonly"></textarea>
</div>
</div>
<div class="row">
<button class="ui button" onclick="send()">Send</button>
</div>
</div>
</div>
<script>
const socketConn = new WebSocket('ws://localhost:8080/socketHandler');
function send() {
const clientMsg = document.getElementById('myMessage');
if (clientMsg.value) {
socketConn.send(clientMsg.value);
}
}
socketConn.onmessage = (e) => {
const output = document.getElementById('output');
output.value += `${e.data}\n`;
}
</script>
</body>
</html>
index.html
包含应用的客户端接口。
const socketConn = new WebSocket('ws://localhost:8080/socketHandler');
在 JavaScript 中,我们创建一个套接字连接。
function send() {
const clientMsg = document.getElementById('myMessage');
if (clientMsg.value) {
socketConn.send(clientMsg.value);
}
}
单击按钮后,我们将发送带有send()
的短信。
socketConn.onmessage = (e) => {
const output = document.getElementById('output');
output.value += `${e.data}\n`;
}
收到响应后,将调用onmessage()
事件处理程序。 我们获得响应数据并将其添加到文本区域。
在本教程中,我们创建了一个支持 WebSocket 的简单 Spring Web 应用。