我正在尝试实现简单的应用程序,其中未经身份验证的用户只需输入组名称并向组发送消息即可。
配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSockConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-reg").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/all","/personal");
}
}
控制器
@Controller
public class HomeController {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
private final Map<String, List<String>> groupSessions = new HashMap<>();
@MessageMapping("/group/{groupName}/join")
public void joinGroup(@DestinationVariable String groupName, SimpMessageHeaderAccessor headerAccessor) {
groupSessions.computeIfAbsent(groupName, k -> new ArrayList<>()).add(headerAccessor.getSessionId());
}
@MessageMapping("/group/{groupName}/send")
public void sendToGroup(@DestinationVariable String groupName, Message<String> message) throws IOException {
for ( String session : groupSessions.get(groupName)){
//Just adding all these 3 methods calls i have tried, None worked
//On debugging this method is being invoked and session variable is not null
simpMessagingTemplate.convertAndSendToUser(session,"/personal",message);
simpMessagingTemplate.send("/personal",message);
simpMessagingTemplate.send(message);
}
}
}
HTML 中的 JavaScript
<script>
const socket = new SockJS('http://localhost:8080/ws-reg');
const stompClient = Stomp.over(socket);
function joinGroup() {
const groupName = document.getElementById('groupInput').value;
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/personal', function(greeting){
console.log(JSON.parse(greeting.body));
});
});
stompClient.send(`/app/group/${groupName}/join`, {}, JSON.stringify({}));
}
function sendMessage() {
const groupName = document.getElementById('groupInput').value;
const messageContent = document.getElementById('messageInput').value;
stompClient.send(`/app/group/${groupName}/send`, {}, JSON.stringify({ content: messageContent }));
}
</script>
我的期望:
用户一:输入“group1”并加入
用户二:输入“group1”并加入
用户三:输入“group2”并加入
当用户一发送消息时,它应该仅传递给用户一和用户二的 websocket。
调试时,任何用户的 Websocket 中都没有新消息或任何事件的日志。 sendToGroup方法被触发并且会话id不为空
编辑: 通过遵循这个 Spring 会话 + Spring Web 套接字。根据会话 ID 向特定客户端发送消息 并进行了一些试验和错误,我可以通过执行以下代码向所有组发送消息:
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor
.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(session);
headerAccessor.setLeaveMutable(true);
simpMessagingTemplate.convertAndSend("/personal",message.getPayload(),headerAccessor.getMessageHeaders()
但是仍然向单个用户/会话发送消息不起作用,尝试了以下代码:
simpMessagingTemplate.convertAndSendToUser(session,"/personal",message.getPayload(),headerAccessor.getMessageHeaders());
我遇到了同样的问题,并且使用 setAllowedOriginPatterns 对我有用。我已经更改了你的代码,尝试一下它应该可以工作。
@Configuration
@EnableWebSocketMessageBroker
public class WebSockConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/wsreg").setAllowedOriginPatterns("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/all","/personal");
}
}