【问题标题】:How to combine Spring REST and WebSocket?如何结合 Spring REST 和 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 吗?

什么是最有效的方法?

【问题讨论】:

    标签: java spring rest websocket


    【解决方案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 发送消息?
    猜你喜欢
    • 2019-09-20
    • 2017-06-20
    • 2014-02-12
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 2015-07-12
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多