2017-02-16 30 views
1

我的目標是將具有正確頭的瀏覽器客戶端連接到服務器。我從StompClient傳遞這些頭文件。基於從UI傳遞的令牌在服務器端斷開WebSocket

,其中i。在頭中傳遞令牌我的UI代碼是

function connect() { 
    var socket = new SockJS('/websocket/api/add'); 
    stompClient = Stomp.over(socket); 
    stompClient.connect({"token" : "12345"}, function(frame) { 
     setConnected(true); 
     console.log('Connected: ' + frame);     
    }); 
} 

在後端我能夠讀在preSend()的報頭的方法ChannelInterceptorAdapter

@Override 
public Message<?> preSend(Message<?> message, MessageChannel channel) { 
    MessageHeaders headers = message.getHeaders(); 
    System.out.println("preSend : HEADERS : {}" + headers); 
    return super.preSend(message, channel); 
} 

但是在這裏我無法關閉wesocket會話。我們怎麼做到這一點?

而且我能關閉WebSocket的會議,但我不能afterConnectionEstablished()WebSocketHandlerDecorator的方法接收頭

public void configureWebSocketTransport(final WebSocketTransportRegistration registration) { 
    registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() { 
     @Override 
     public WebSocketHandler decorate(final WebSocketHandler handler) { 
      return new WebSocketHandlerDecorator(handler) { 
       @Override 
       public void afterConnectionEstablished(final WebSocketSession session) throws Exception { 

        session.close(CloseStatus.NOT_ACCEPTABLE); 
        super.afterConnectionEstablished(session); 
       } 
      }; 
     } 
    }); 
    super.configureWebSocketTransport(registration); 
} 

有人能指導我如何關閉基於websocketsession在我們從服務器端的用戶界面傳遞的標題上?

回答

1

您可以嘗試在建立連接時通過消息將客戶端的令牌發送到服務器,然後讓服務器將該會話保存到映射中,該映射的關鍵是相應的令牌。

因此,當您想通過令牌關閉會話時,可以使用令牌從該映射查詢會話。


示例代碼:

保存其令牌會話:

@Override 
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { 
    String messageToString = message.getPayload().toString(); 
    if (messageToString.startsWith("token=")) { 
     tokenToSessionMapping.put(messageToString.substring("token=".length())); 
    } 
    // Other handling message code... 
} 

通過令牌關閉會話:

WebSocketSession sessionByToken = tokenToSessionMapping.get(token); 
if (sessionByToken != null && sessionByToken.isOpen()) { 
    sessionByToken.close(CloseStatus.NOT_ACCEPTABLE); 
} 

還有其它的事情需要注意:

  1. 由於tokenToSessionMapping是靜態的,並在會話中共享。您應該使用線程安全的實現,例如ConcurrentHashMap。

  2. 當會話關閉時,您最好從地圖tokenToSessionMapping中刪除相應的條目。否則,地圖大小將保持增長。您可以通過替代方法afterConnectionClosed()來完成此操作。

    @Override 
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { 
        Log.info("Socket session closed: {}", status.toString()); 
        String foundKey = null; 
        for (Map.Entry<String, String> entry : tokenToSessionMapping.entrySet()) { 
         if (Objects.equals(entry.getValue(), session)) { 
          foundKey = entry.getKey(); 
         } 
        } 
        if (foundKey != null) { 
         tokenToSessionMapping.remove(foundKey); 
        } 
    } 
    
+0

非常感謝您的指點我朝着正確的方向:) –

+0

沒問題:)雖然我認爲有可能是一個更好的解決辦法? – wings

相關問題