如何结合 Spring REST 和 WebSocket?
Posted
技术标签:
【中文标题】如何结合 Spring REST 和 WebSocket?【英文标题】:How to combine Spring REST and WebSocket? 【发布时间】:2021-01-25 20:02:52 【问题描述】:我是 Spring 新手,正在从事一个大学项目。
目标:拥有一个 REST POST 端点,既可以保存数据,又可以使用 websocket 发送广播消息。
现在,我的 RestController 似乎工作正常,但真的不知道如何实现 websocket 部分?
这是端点的样子:
@PostMapping("/employees")
Employee newEmployee(@RequestBody Employee newEmployee)
return repository.save(newEmployee);
我之前的想法:
-使用带有@SendTo 注解的方法创建@Controller?
-我可以在 RestController newEmployee 方法上使用@SendTo 吗?
什么是最有效的方法?
【问题讨论】:
【参考方案1】:就像spring提供了@RestController一样,它也提供了@EnableWebSocket注解和处理双向通信的方法,下面是spring创建websocket连接的分步方法 首先创建一个配置类来制作我们的 WebSocketConnection 类 bean,它将作为 websocket 连接、断开连接和来自客户端的消息的处理程序,并将其添加到 WebSocketHandlerRegister 及其命名空间。
import org.springframework.context.annotation.Bean;
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 WebSocketConfiguration implements WebSocketConfigurer
@Bean
public WebSocketConnection getWebSocketConnection()
return new WebSocketConnection();
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry)
webSocketHandlerRegistry.addHandler(getWebSocketConnection(), "/websocket");
现在让我们创建 WebSocketConnection 类
public class WebSocketConnection extends TextWebSocketHandler
private static final Logger log = LoggerFactory.getLogger(WebSocketConnection.class);
private static final Gson gson = new GsonBuilder().create();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception
log.info("connected with the websocket client : " + session.getId());
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception
JsonObject parsedMessage = gson.fromJson(message.getPayload(), JsonObject.class);
log.info("The message got from the client is " + parsedMessage);
JsonObject responseMessage = new JsonObject();
responseMessage.addProperty("response", "Your response was recorded by the server");
responseMessage.addProperty("messageReceivedtime", LocalDateTime.now().toLocalDate().toString());
int max = 100;
int min = 20;
responseMessage.addProperty("randomNo", (int) Math.floor(Math.random() * (max - min + 1) + min));
session.sendMessage(new TextMessage(responseMessage.toString())); //sending message back to the client
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception
log.info("connection closed from the websocket client : " + session.getId());
到这里就完成了。 现在从 javascript 的客户端,你将不得不像下面那样制作 websocket 客户端对象
const webSocketClient = new WebSocket('ws://localhost:port/websocket');
//const webSocketClient = new WebSocket('wss://ip:port/websocket') for cases of secure connection
关于javascript中WebSocket客户端的更多信息,请参考这个https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
您提到了您的目标,即 '有一个保存数据的 REST POST 端点,但也使用 websocket 发送广播消息'不应该在 1 中。 您可以做的是,当用户保存数据时,您可以将服务器的响应返回给已保存数据的用户,然后让该用户向 websocket 服务器发送消息,websocket 服务器将广播给其他用户。
【讨论】:
您好,女士。感谢你的回答。如何在 RestController 中使用这个 Handler? @jhthewow,您可以将 WebSocketConnection 类视为本身具有请求映射'/websocket'的控制器 我想要实现的流程如下: 1. 用户向定义的 REST 端点发送 POST 请求(在描述中) 2. 端点做了两件事:(a)保存数据 -this工作 - (b) 使用 websocket 将数据作为广播消息发送给订阅的客户端。我需要 (b) 方面的帮助。命中 POST 端点后,如何从 RestController 发送消息?以上是关于如何结合 Spring REST 和 WebSocket?的主要内容,如果未能解决你的问题,请参考以下文章