我正在尝试实现一个简单的websockets应用程序,它可以将消息从一个端点发送到其他地方建立的指定会话。到目前为止,我已经能够使用注释@SendToUser(),以便客户端订阅一个频道(如本问题所述:Spring Websockets @SendToUser without login?)
但是,我现在想要创建一个单独的端点,在调用时,它会查找与传递到此端点的数据相关联的用户,并向该用户发送有关此数据的消息。
但是,我无法准确地确定如何制作它以便我可以调用SimpMessagingTemplate convertAndSendToUser()命令,因为我的用户没有Principal(我没有使用Spring Security)。
我已经能够从传递给@MessageMapping端点的MessageHeaders获取simpSessionId,但现在我无法弄清楚如何使用simpSessionId从我的应用程序的不同部分发送信息。
我已经做了一些关于覆盖DefaultHandshakeHandler的determineUser()方法的研究,并在成功的websocket握手时将随机生成的UUID作为用户名分配给用户(如本问题的答案中所述:How to reply to unauthenticated user in Spring 4 STOMP over WebSocket configuration?) ,但由于主体即将出现,我不确定如何正确生成一个并将其分配给Principal以便与应用程序一起使用。
我基本上需要能够拥有匿名用户,并在他们创建websocket连接后从应用程序的不同部分向他们发送消息。
答案 0 :(得分:3)
因此,对于遇到类似问题的其他人,我实施了自己的Principal类:
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);
}
}
然后,我实现了我自己的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;
}
}
现在,当握手发生时,websocket会话会将此主体分配给它,因此如果用户是匿名的,他们会获得一个匿名主体,这将允许我存储他们的名字(生成的UUID)以供以后在其他部分使用。应用