在Spring Boot(Websockets)中
我刚刚看到了这个例子:
messaging.convertAndSendToUser( username, "/queue/notifications", new Notification("You just got mentioned!"));
那家伙从哪里获得用户名?我找不到关于从何处获取该用户名的任何提及…
这个答案是基于以下应用程序编写的:https : //github.com/spring-guides/gs-messaging-stomp- websocket
为了注册用户,必须首先创建一个代表该用户的对象,例如:
public final class User implements Principal { private final String name; public User(String name) { this.name = name; } @Override public String getName() { return name; } }
然后,您将需要一种创建这些User对象的方法。一种方法是在SockJS向您发送连接消息头时。为此,您需要拦截连接消息。您可以通过创建我们的拦截器来做到这一点,例如:
User
SockJS
public class UserInterceptor extends ChannelInterceptorAdapter { @Override public Message<?> preSend(Message<?> message, MessageChannel channel) { StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); if (StompCommand.CONNECT.equals(accessor.getCommand())) { Object raw = message .getHeaders() .get(SimpMessageHeaderAccessor.NATIVE_HEADERS); if (raw instanceof Map) { Object name = ((Map) raw).get("name"); if (name instanceof LinkedList) { accessor.setUser(new User(((LinkedList) name).get(0).toString())); } } } return message; } }
拥有该地址后,您还必须注册this UserInterceptor。我猜您在应用程序中的某个位置定义了配置AbstractWebSocketMessageBrokerConfigurer类。在此类中,您可以通过覆盖configureClientInboundChannel方法注册用户拦截器。您可以这样做:
UserInterceptor
AbstractWebSocketMessageBrokerConfigurer
configureClientInboundChannel
@Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.setInterceptors(new UserInterceptor()); }
最后,当您的客户连接时,他们必须提供其用户名:
stompClient.connect({ name: 'test' // Username! }, function () { console.log('connected'); });
完成所有设置后,simpUserRegistry.getUsers()将返回用户列表,您将可以使用convertAndSendToUser方法:
simpUserRegistry.getUsers()
convertAndSendToUser
messaging.convertAndSendToUser("test", ..., ...);
编辑
进一步测试一下,在订阅时,您必须为主题加上前缀/useras,SimpMessagingTemplate并将其用作默认前缀,例如:
/user
SimpMessagingTemplate
stompClient.subscribe('/user/...', ...);
我也犯了一个错误UserInterceptor并纠正了它(名称解析部分)。