2017-04-04 134 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),以便以後在應用程序的其他部分使用。