2017-04-04 133 views
0

我想实现一个简单的websockets应用程序,可以将消息从一个端点发送到其他地方建立的指定会话。到目前为止,我已经能够使用注释@SendToUser()为了客户端订阅一个通道(如在这个问题中讨论:Spring Websockets @SendToUser without login?没有主体的春季websockets

但是,我现在想创建一个单独的端点,当称为查找与传递到此端点的数据相关的用户,并向该用户发送有关此数据的消息。

但是,我还没有能够准确地确定如何使它可以调用SimpMessagingTemplate convertAndSendToUser()命令,因为我的用户没有主体(我没有使用Spring Security)。

我已经能够从传递给@MessageMapping端点的MessageHeaders获取simpSessionId,但现在我不知道如何使用simpSessionId从我的应用程序的不同部分发送信息。

我已经做了关于覆盖DefaultHandshakeHandler的determineUser()方法,并指定一个随机生成的UUID作为用户名,以在成功的WebSocket握手用户(如在回答这个问题描述:How to reply to unauthenticated user in Spring 4 STOMP over WebSocket configuration?)一些研究,但由于主要是空的我不确定如何正确地生成一个,并将其分配给委托人用于应用程序。

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

回答

1

因此,对于任何人面临着类似的问题,我实现了我自己主要的类:

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会话得到这个在Handshake发生时分配给它的主体,因此如果用户是匿名的,他们将获得一个匿名主体,这个主体将允许我存储他们的名字(生成的UUID),以便以后在应用程序的其他部分使用。