在下面的解决方案中,我编写了客户端和后端代码片段。我们需要在客户端代码中以
/user
开头放置socket主题。否则,客户端将无法监听socket。
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocketConfig.java
package com.oktaykcr.notificationservice.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket").setAllowedOriginPatterns("*");
registry.addEndpoint("/socket").setAllowedOriginPatterns("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/file");
registry.setApplicationDestinationPrefixes("/app");
}
}
WebSocketContoller.java
package com.oktaykcr.notificationservice.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
Logger logger = LoggerFactory.getLogger(WebSocketController.class);
@MessageMapping("/socket")
@SendTo("/file/status")
public String fileStatus(@Payload String message) {
logger.info(message);
return message;
}
}
您可以从任何地方向套接字发送消息。在我的情况下,我的principal.getName()等于userId。
simpMessagingTemplate.convertAndSendToUser(userId, "/file/status", socketMessage);
客户端 (使用ReactJs和react-stomp)
App.js
import './App.css';
import SockJsClient from 'react-stomp'
import { useRef } from 'react';
function App() {
const clientRef = useRef();
const sendMessage = (msg) => {
clientRef.current.sendMessage('/app/socket', msg);
}
return (
<div className="App">
<div>
<button onClick={() => sendMessage("Hola")}>Send</button>
</div>
<SockJsClient url='http://localhost:9090/notification-service/socket' topics={['/user/file/status']}
onMessage={(msg) => { console.log(msg); }}
ref={(client) => { clientRef.current = client }} />
</div>
);
}
export default App;
SockJsClient元素的url属性为http://localhost:9090/notification-service/socket
。http://localhost:9090
是Api Gateway的IP地址,notification-service
是微服务的名称,/socket
在WebSocketConfig.java中定义。
simpMessagingTemplate.convertAndSendToUser(principal.getName(), "/user/reply", reply);
,当消息从服务器发送时,它会抛出以下异常java.lang.IllegalArgumentException: Expected destination pattern "/principal/{userId}/**"
。 - gerrytanconvertAndSendToUser(principal.getName(), "/reply", reply);
- Tip-Sy