本文将逐步介绍如何在 Spring Boot 中配置 WebSocket 并将其与 React 配合使用。
依赖项
我们只需要两个依赖项,尽量减少所需的依赖项数量。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
配置
接下来,我们将创建 WebSocketConfig
配置类。它实现了 WebSocketMessageBrokerConfigurer
,并注释了 Configuration
和 EnableWebSocketMessageBroker
。
Configuration
表示该类是 Spring 配置类,用于为应用程序定义 Spring Bean 和配置。
@EnableWebSocketMessageBroker
在应用程序中启用基于 WebSocket 的消息传递,并将其配置为消息代理。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/")
.setAllowedOrigins("http://localhost:3000")
.withSockJS();
}
}
现在,让我们来看看 WebSocketConfig
类中的方法:
配置消息代理
configureMessageBroker(MessageBrokerRegistry config):
该方法用于配置 WebSocket 的消息代理。
config.enableSimpleBroker("/topic")
启用简单消息代理,允许客户端订阅和接收来自指定目标前缀(即/topic)的消息。服务器发送到以 /topic 开头的主题的消息将广播给连接的客户端。
config.setApplicationDestinationPrefixes("/app")
设置应用程序目标前缀。客户端可以向以此前缀开头的目的地发送信息。例如,客户端可以向 /app/destination 发送信息。
注册 Stomp 端点
registerStompEndpoints(StompEndpointRegistry registry)
注册一个客户可以连接的 Stomp(面向简单文本的消息传递协议)端点。
registry.addEndpoint("/")
将根端点(i.e., “/”)注册为 WebSocket 端点。客户端可以连接到该端点来建立 WebSocket 连接,我们将在 React 应用程序中看到如何实现。
withSockJS()
支持 SockJS,这是一个 JavaScript 库,为不直接支持 WebSocket 的浏览器提供类似 WebSocket 的接口。这样可以实现更广泛的客户端兼容性。
控制器
下面创建一个简单的控制器:
@Slf4j
@Controller
public class WebSocketController {
private final Map<String, List<UserText>> chats = new HashMap<>();
@MessageMapping("/chat/{chatId}")
@SendTo("/topic/chat/{chatId}")
public List<UserText> sendMessageWithWebsocket(@DestinationVariable String chatId,
@Payload Message<UserText> message) {
log.info("new message arrived in chat with id {}", chatId);
List<UserText> messages = this.chats.getOrDefault(chatId, new ArrayList<UserText>());
messages.add(message.getPayload());
chats.put(chatId, messages);
return messages;
}
}
在这里,我们将消息存储在一个名为 messages 的数组中,然后将该数组存储在一个以聊天 ID 为标识符的映射中。通过注解 @DestinationVariable
,我们可以获得聊天 ID。每个用户都将订阅不同的对话,并只能查看该聊天中的消息。
启动应用程序并在终端运行以下命令,检查是否能成功连接到 WebSocket 端点。
wscat -c ws://localhost:8080/websocket
构建简单的 React 应用程序
要连接 React,需要以下依赖关系:
npm install --save @stomp/stompjs
编辑App.tsx
:
import { Client } from '@stomp/stompjs';
import { useEffect, useState } from 'react';
import './App.css';
import logo from './logo.svg';
function App() {
let client: Client | null = null;
const [chatId, setChatId] = useState("")
useEffect(() => {
// Create a WebSocket connection
client = new Client();
// Configure the WebSocket endpoint URL
const websocketUrl = 'ws://localhost:8080/websocket'; // Replace with your WebSocket endpoint URL
// Connect to the WebSocket server
client.configure({
brokerURL: websocketUrl,
debug: function (str) {
console.log(str);
},
onConnect: () => {
// Perform actions after successful connection
const destination = `/topic/chat/${chatId}`; // Specify the destination for the server-side message handler
client && client.subscribe(destination, (message) => {
console.log('Received message:', JSON.parse(message.body));
// Process the received message as needed
});
},
// You can add more event handlers and configuration options as needed
});
// Connect to the WebSocket server
client.activate();
// Clean up the connection on component unmount
return () => {
client && client.deactivate();
};
}, [chatId]);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<input type='text' aria-label='ChatId' onChange={(event) => {
console.log(event)
setChatId(event.target.value)
}}></input>
<button onClick={() => {
const destination = `/app/chat/${chatId}`; // Specify the destination for the server-side message handler
const message = 'Hello, server!'; // Specify the message to send
if (client != null) {
client.publish({
destination,
body: JSON.stringify({
data: message,
userId: 1 // Specify a user ID
}),
});
}
}}>Send</button>
</p>
</header>
</div>
);
}
export default App;
以上代码完整Github地址: https://github.com/lejdiprifti/medium
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。