本文介绍了简单:convertAndSendToUser我从哪里获得用户名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Spring Boot(Websockets)中

In Spring Boot (Websockets)

我刚刚看到了这个例子:

I just saw this example:

messaging.convertAndSendToUser( username, "/queue/notifications",
                       new Notification("You just got mentioned!"));

该人从哪里获得用户名?我找不到关于从何处获取该用户名的任何提及...

Where does the guy get a username from? I can't find any mention about where to get that username...

推荐答案

此答案是根据以下应用程序编写的: https://github.com/spring-guides/gs-messaging-stomp-websocket

This answer is written based on this application: https://github.com/spring-guides/gs-messaging-stomp-websocket

要注册用户,必须首先创建一个代表该用户的对象,例如:

In order to register a user, you must first create an object that will represent it, for example:

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向您发送连接消息头.为此,您需要拦截连接消息.您可以通过创建我们的拦截器来做到这一点,例如:

Then you'll need a way to create these User objects. One way of doing it is when SockJS sends you the connect message headers. In order to do so, you need to intercept the connect message. You can do that by creating our your interceptor, for example:

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类.在此类中,您可以通过覆盖configureClientInboundChannel方法来注册用户拦截器.您可以这样做:

Once you have that, you must also register this UserInterceptor. I'm guessing somewhere in your application you have defined a configuration AbstractWebSocketMessageBrokerConfigurer class. In this class you can register your user interceptor by overriding configureClientInboundChannel method. You can do it like this:

@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
    registration.setInterceptors(new UserInterceptor());
}

最后,当您的客户连接时,他们将必须提供其用户名:

And then finally, when your clients connect, they'll have to provide their usernames:

stompClient.connect({
    name: 'test' // Username!
}, function () {
    console.log('connected');
});

完成所有设置后,simpUserRegistry.getUsers()将返回用户列表,您将可以使用convertAndSendToUser方法:

After you have all this setup, simpUserRegistry.getUsers() will return a list of users and you'll be able to use convertAndSendToUser method:

messaging.convertAndSendToUser("test", ..., ...);

修改

进一步测试一下,订阅时,您必须为主题加上/user前缀,因为SimpMessagingTemplate将此主题用作默认前缀,例如:

Testing this out a bit further, when subscribing, you'll have to prefix your topics with /user as SimpMessagingTemplate uses this as a default prefix, for example:

stompClient.subscribe('/user/...', ...);

我在UserInterceptor中也犯了一个错误,并对其进行了更正(名称解析部分).

Also I had made a mistake in UserInterceptor and corrected it (name parsing part).

这篇关于简单:convertAndSendToUser我从哪里获得用户名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 09:38