简单:convertAndSendToUser 我从哪里获得用户名?
Simple: convertAndSendToUser Where do I get a username?
在 Spring 引导中(Websockets)
我刚看到这个例子:
messaging.convertAndSendToUser( username, "/queue/notifications",
new Notification("You just got mentioned!"));
这家伙从哪里得到用户名的?我找不到关于从哪里获得该用户名的任何提及...
这个答案是基于这个应用写的:https://github.com/spring-guides/gs-messaging-stomp-websocket
为了注册用户,您必须首先创建一个 object 来代表它,例如:
public final class User implements Principal {
private final String name;
public User(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
然后您需要一种方法来创建这些 User
object。一种方法是在 SockJS
向您发送连接消息 headers 时。为此,您需要拦截连接消息。您可以通过创建我们的拦截器来做到这一点,例如:
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;
}
}
一旦你有了它,你还必须注册这个 UserInterceptor
。我猜你在应用程序的某处定义了一个配置 AbstractWebSocketMessageBrokerConfigurer
class。在此 class 中,您可以通过覆盖 configureClientInboundChannel
方法来注册您的用户拦截器。你可以这样做:
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new UserInterceptor());
}
最后,当您的客户连接时,他们必须提供他们的用户名:
stompClient.connect({
name: 'test' // Username!
}, function () {
console.log('connected');
});
完成所有这些设置后,simpUserRegistry.getUsers()
将 return 用户列表,您将能够使用 convertAndSendToUser
方法:
messaging.convertAndSendToUser("test", ..., ...);
编辑
进一步测试,订阅时,您必须在主题前加上 /user
前缀,因为 SimpMessagingTemplate
使用此作为默认前缀,例如:
stompClient.subscribe('/user/...', ...);
另外我在UserInterceptor
中犯了一个错误并更正了它(名称解析部分)。
在 Spring 引导中(Websockets)
我刚看到这个例子:
messaging.convertAndSendToUser( username, "/queue/notifications",
new Notification("You just got mentioned!"));
这家伙从哪里得到用户名的?我找不到关于从哪里获得该用户名的任何提及...
这个答案是基于这个应用写的:https://github.com/spring-guides/gs-messaging-stomp-websocket
为了注册用户,您必须首先创建一个 object 来代表它,例如:
public final class User implements Principal {
private final String name;
public User(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
然后您需要一种方法来创建这些 User
object。一种方法是在 SockJS
向您发送连接消息 headers 时。为此,您需要拦截连接消息。您可以通过创建我们的拦截器来做到这一点,例如:
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;
}
}
一旦你有了它,你还必须注册这个 UserInterceptor
。我猜你在应用程序的某处定义了一个配置 AbstractWebSocketMessageBrokerConfigurer
class。在此 class 中,您可以通过覆盖 configureClientInboundChannel
方法来注册您的用户拦截器。你可以这样做:
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new UserInterceptor());
}
最后,当您的客户连接时,他们必须提供他们的用户名:
stompClient.connect({
name: 'test' // Username!
}, function () {
console.log('connected');
});
完成所有这些设置后,simpUserRegistry.getUsers()
将 return 用户列表,您将能够使用 convertAndSendToUser
方法:
messaging.convertAndSendToUser("test", ..., ...);
编辑
进一步测试,订阅时,您必须在主题前加上 /user
前缀,因为 SimpMessagingTemplate
使用此作为默认前缀,例如:
stompClient.subscribe('/user/...', ...);
另外我在UserInterceptor
中犯了一个错误并更正了它(名称解析部分)。