当前位置: 首页 > 知识库问答 >
问题:

如何在初次握手时从SpringWebSocket中检索会话ID并在以后使用?

夏志国
2023-03-14

如何在初次握手时从SpringWebSocket中检索会话ID并在以后使用?

目标无论何时Websocket客户端连接到Websocket服务器,目标都是。websocket客户端将传入一个参数。它将通过他们的租户。成功连接到websocket服务器后。websocket服务器通常会生成会话ID。我希望实现的是将此websocket sessionID与特定租户参数相关联。稍后,每当websocket服务器向该客户机/租户发送更新时。它将通过websocket服务器创建的会话ID将其发送给特定租户。

这是我的websocket服务器配置。。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/queue");
        config.setApplicationDestinationPrefixes("/app");
    }


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //registry.addEndpoint("/client").addInterceptors(new WSHandshakeInterceptor()).withSockJS();
        registry.addEndpoint("/agent").addInterceptors(new WSHandshakeInterceptor()).withSockJS();
    }
}

WSHandhsakeInterceptor。JAVA

public class WSHandshakeInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        return true;
    }


    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
        HttpHeaders header = serverHttpRequest.getHeaders();
        String client = header.get("client-id").get(0);
        String sessionId = null;
        if (serverHttpRequest instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) serverHttpRequest;
            HttpSession session = servletRequest.getServletRequest().getSession();
            sessionId = session.getId();
            System.out.println("Session ID + "+sessionId);
            System.out.println("CLIENT ID "+client);
            ClassChangeNotificationServiceImpl.clientSessionMap.put(client, sessionId);
        }
    }
}

下面是我的websocket客户端如何连接到服务器。

WebSocketClient simpleWebSocketClient = new StandardWebSocketClient();
        List<Transport> transports = new ArrayList<>(1);
        transports.add(new WebSocketTransport(simpleWebSocketClient));
        SockJsClient sockJsClient = new SockJsClient(transports);
        stompClient = new WebSocketStompClient(sockJsClient);
        stompClient.setMessageConverter(new MappingJackson2MessageConverter());
        String url = "ws://localhost:8081/agent";
        sessionHandler = new MyStompSessionHandler();
        try {
            WebSocketHttpHeaders wsHTTPheaders = new WebSocketHttpHeaders();
            wsHTTPheaders.add("CLIENT-ID","XXXTESTCLIENTXXX");
            session = stompClient.connect(url, wsHTTPheaders,sessionHandler).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

MyStompSessionHandler.java

import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class  MyStompSessionHandler extends StompSessionHandlerAdapter {

    private void subscribeTopic(String topic, StompSession session) {
        session.subscribe(topic, new StompFrameHandler() {
            @Override
            public Type getPayloadType(StompHeaders headers) {

                System.out.println("HANDLER");
                return String.class;
            }

            @Override
            public void handleFrame(StompHeaders headers, Object payload) {
                System.out.println("TEST HEKHEk");
            }
        });

    }

    @Override
    public Type getPayloadType(StompHeaders headers) {
        return String.class;
    }

    /**
     * This implementation is empty.
     */
    @Override
    public void handleFrame(StompHeaders headers, Object payload) {
        String resp = (String) payload;
        System.out.println("Received responses from websocket server: "+ resp);
    }

    @Override
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
        subscribeTopic("/user/queue/response", session);

        System.out.println("CONNECTEd");
        for(Map.Entry<String, List<String>> entry: connectedHeaders.entrySet()) {
            System.out.println(entry.getKey()+"S");
        }
    }
}

现在有趣的部分。或者我一直在努力实现的目标。是我可以通过这个代码向网络插座客户端发送更新

this.template.convertAndSendToUser(client, "/queue/reply", message);

其中客户端是Spring生成的会话ID。它将仅向该特定客户端发送消息

问题握手成功后如何检索会话ID??我是否可以使用此会话ID向该客户端发送特定的更新。这是我的代码...

共有1个答案

龙霖
2023-03-14

只需在代码中的任何位置添加此方法,即可在握手后获得会话ID:

@EventListener
    private void handleSessionConnected(SessionConnectEvent event) {
        String sessionId = SimpAttributesContextHolder.currentAttributes().getSessionId();
    }
 类似资料:
  • SSO/SAML使用OKTA API与SP一起工作。我的问题是,有没有一种方法可以从我的应用程序中获取当前的OKTA会话Id?

  • 问题内容: 为了进行记录,我想创建一个记录器,该记录器将当前会话的ID自动添加到记录的行中。 对于已登录的用户,这不是问题: 问题是,在用户登录之前的回报。是否有另一种获取会话ID的方法,而无需引用当前响应或此类响应? 问题答案: 您可以使用 这依赖于Spring的,因此应与Spring MVC一起使用,否则您应该有一个声明。如果不存在,还将创建会话。

  • 我需要向API服务发送一个post请求,该服务需要一个会话id以及post请求字段中的其他参数,以便获得所需的信息。 我正在使用邮递员来测试这个API。 我想知道在使用Postman时,如何在帖子请求中发送“会话ID”? 我知道Postman中的预请求脚本,但我不知道如何在post请求中使用该变量。

  • 问题内容: 我正在尝试将Redis会话集成到用Node.js编写的身份验证系统中。 我已经能够成功设置Redis服务器和Express服务器。 这是我的设置(只是重要的一点): 现在…我该如何实际创建,阅读和销毁会话?我已经阅读了很多关于如何设置的文章以及关于SO的许多问题,但是我发誓每个都只停留在配置上,并且不解释如何实际使用它… 我知道这可能非常简单,但是请不要投票,而只是解释一下:)。 问题

  • 我正在Codeigniter中创建API。在这个API中,我为用户提供了一个登录函数。如果登录成功,我将在CI会话中设置用户数据,并将会话返回给用户。 现在,用户可以使用该会话ID来验证他自己的所有其他请求,如添加/更新/删除。基本上,我希望当用户发送下一个请求时,我可以根据他的会话ID验证他的凭据。 客户请求代码: 上面是一个从客户端到服务器的登录请求示例。在服务器端,服务器验证客户端提供的凭据

  • 我正在创建一个Android应用程序,它将存储价值列表,例如。特定用户定义名称下不同时间的温度值。我打算使用SQLite来存储值,我读到使用Room将为它提供一个ORM层,所以我使用了它。但是后来我遇到了一个异常,基本上说我不能从主线程打开数据库连接,所以我尝试使用LiveData进行插入和检索。现在我有两张桌子。我只是想展示它们的结构,而不是在句法上准确: 最初,我考虑不强制外键关系,只在插入P