当用户连接时获取原生标头

7

我有客户端通过websocket进行连接

var socket = new SockJS(this.props.stomp);
var stompClient = Stomp.over(socket);
var channel = "/room."+this.props.room.uid
var app = this;
stompClient.connect({room: this.props.room.uid}, function(frame) {
....

我正在尝试按照教程获取Java后端中的此标题:

public void onApplicationEvent(SessionConnectEvent event) {
    StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());

    String  room = sha.getNativeHeader("room").get(0);
    logger.debug("Connect event [sessionId: " + sha.getSessionId() +"; room: "+ room + " ]");
}

但是此时 room 为空。
我进行了调试并发现了一个非常复杂的层次结构:一个 MessageHeaderAccessor 包含一个包含 LinkedList 的 map,其中有一个名为 nativeHeaders 的键来包含这些本机标头。
我的问题是:是否有一种简单的方法来访问这个本机标头?到目前为止,我只得到了像下面这样的东西。

MessageHeaderAccessor accessor = NativeMessageHeaderAccessor.getAccessor(event.getMessage(), SimpMessageHeaderAccessor.class);
accessor.getMessageHeaders();
Object header = accessor.getHeader("simpConnectMessage");
GenericMessage<?> generic = (GenericMessage<?>) accessor.getHeader("simpConnectMessage");
System.out.println(generic.getHeaders().get("nativeHeaders"));

我发现有些东西很难理解和使用。实际上,我想要的仅仅是追踪连接到频道的当前用户数量,我认为实现一个ApplicationListener就可以了。也许我错了,如果有人发现了类似的东西或者已经实现了,我想知道。

2个回答

3
我是这样做的:

我用了以下方法:

  1. javascript snippet

    function connect() {
        var socket = new SockJS('http://localhost:8081/ws/notification');
        stompClient = Stomp.over(socket);
    
        var header = {
            "user-id" : "bb2c9039-0ed3-4d6f-b078-db965286944d"
        }
    
        stompClient.connect(header, function (frame) {
            console.log('Connected: ' + frame);
            stompClient.subscribe('/user/ws/notification/message', function (greeting) {
                showGreeting(JSON.parse(greeting.body).name);
            });
        });
    }
    
  1. Java snippet

    @EventListener
    public void handleWebSocketConnectListener(SessionConnectedEvent event) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(event.getMessage());
    
        String sessionId = accessor.getMessageHeaders().get(SimpMessageHeaderAccessor.SESSION_ID_HEADER, String.class);
        String userId = getUserId(accessor);
    
        log.info("User( user-id: {} ) established new WebSocket session( session-id: {} ).", userId, sessionId);
        putSessionIdToMap(sessionId, userId);
    }
    
    private String getUserId(StompHeaderAccessor accessor) {
        GenericMessage<?> generic = (GenericMessage<?>) accessor.getHeader(SimpMessageHeaderAccessor.CONNECT_MESSAGE_HEADER);
        if (nonNull(generic)) {
            SimpMessageHeaderAccessor nativeAccessor = SimpMessageHeaderAccessor.wrap(generic);
            List<String> userIdValue = nativeAccessor.getNativeHeader("user-id");
    
            return isNull(userIdValue) ? null : userIdValue.stream().findFirst().orElse(null);
        }
    
        return null;
    }
    

0

对于 handleWebSocketConnectListener(SessionConnectedEvent event)

在使用Intellij的调试功能后,我发现这个方法是有效的!

MessageHeaderAccessor headerAccessor = 
     MessageHeaderAccessor.getAccessor(event.getMessage().getHeaders(), 
     MessageHeaderAccessor.class);
StompHeaderAccessor stompHeaderAccessor = MessageHeaderAccessor.getAccessor(
                (Message<?>) headerAccessor.getHeader("simpConnectMessage"),
                StompHeaderAccessor.class) ;
String token = stompHeaderAccessor.getNativeHeader("Authorization").get(0);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接