Spring websocket没有主体

Ben*_*der 2 spring anonymous stomp principal websocket

我正在尝试实现一个简单的 websockets 应用程序,该应用程序可以将消息从一个端点发送到在其他地方建立的指定会话。到目前为止,我已经能够使用注释 @SendToUser() 以便客户端订阅频道(如本问题中所述:Spring Websockets @SendToUser without Login?

但是,我现在想要创建一个单独的端点,当调用该端点时,它会查找与传递到该端点的数据关联的用户,并向该用户发送有关该数据的消息。

但是,我无法准确确定如何制作它,以便我可以调用 SimpMessagingTemplate ConvertAndSendToUser() 命令,因为我的用户没有主体(我没有使用 Spring Security)。

我已经能够从传递到 @MessageMapping 端点的 MessageHeaders 中获取 simpSessionId,但现在我无法弄清楚如何使用 simpSessionId 从应用程序的不同部分发送信息。

我已经做了一些研究,涉及重写 DefaultHandshakeHandler 的确定用户()方法,并在成功的 websocket 握手时将随机生成的 UUID 作为用户名分配给用户(如此问题的答案中所述:如何在 Spring 4 中回复未经身份验证的用户) STOMP over WebSocket 配置?),但由于出现的主体为 null,我不确定如何正确生成主体并将其分配给主体以供应用程序使用。

我基本上需要能够拥有匿名用户,并在他们创建 websocket 连接后从应用程序的不同部分向他们发送消息。

Ben*_*der 5

因此,对于面临类似问题的其他人,我实现了自己的 Primary 类:

package hello;

import java.security.Principal;
import java.util.Objects;

public class AnonymousPrincipal implements Principal {

    private String name;

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object another) {
        if (!(another instanceof Principal))
            return false;

        Principal principal = (Principal) another;
        return principal.getName() == this.name;

    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我实现了我自己的 DefaultHandshakeHandler 版本:

package hello;

import java.security.Principal;
import java.util.Map;
import java.util.UUID;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

public class CustomHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request,
            WebSocketHandler wsHandler, Map<String, Object> attributes) {
        Principal principal = request.getPrincipal();           

        if (principal == null) {
            principal = new AnonymousPrincipal();

            String uniqueName = UUID.randomUUID().toString();

            ((AnonymousPrincipal) principal).setName(uniqueName);
        }

        return principal;

    }

}
Run Code Online (Sandbox Code Playgroud)

现在,当握手发生时,Websocket 会话会获取分配给它的主体,因此如果用户是匿名的,他们会分配一个匿名主体,这将允许我存储他们的名称(生成的 UUID)以供以后在应用程序的其他部分使用。