代码之家  ›  专栏  ›  技术社区  ›  Romeo Sierra

Spring Boot WebSocket-将主体添加到连接响应中

  •  0
  • Romeo Sierra  · 技术社区  · 7 年前

    我有以下JS函数,它们通过STOMP连接到WebSocket,并处理 onConnected 事件,分别。

    function connect(event) {
        username = document.querySelector('#name').value.trim();
    
        if(username) {
            usernamePage.classList.add('hidden');
            chatPage.classList.remove('hidden');
    
            var socket = new SockJS('/ws');
            stompClient = Stomp.over(socket);
    
            stompClient.connect({}, onConnected, onError);
        }
        event.preventDefault();
    }
    
    
    function onConnected(response) {
        console.log(response);
        // Subscribe to the Public Topic
        stompClient.subscribe('/topic/public', onMessageReceived);
    
        // Tell your username to the server
        stompClient.send("/app/chat.addUser",
            {},
            JSON.stringify({sender: username, type: 'JOIN'})
        )
    
        connectingElement.classList.add('hidden');
    }
    

    现在是函数的第一行 未连接

    {
        command: "CONNECTED",
        headers: { 
            "heart-beat": "0,0",
            version: "1.1"
        },
        body: ""
    }
    

    我也有一个 HttpHandshakeInterceptor HandshakeInterceptor 具体如下。

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Map attributes) throws Exception {
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletRequest.getServletRequest().getSession();
            attributes.put("sessionId", session.getId());
    
            ServletServerHttpResponse servletResponse = (ServletServerHttpResponse) response;
            response.getHeaders().set("KEY","VALUE"); // *** I want this either to be in the response header or the body.
        }
        return true;
    }
    

    具有以开头的注释的行 ***

    1 回复  |  直到 7 年前
        1
  •  2
  •   Romeo Sierra    7 年前

    可以下面是我尝试做的, 无功而返

    public class OutboundMessageInterceptor implements ChannelInterceptor {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(OutboundMessageInterceptor.class);
    
        @Override
        public Message<?> preSend(Message<?> message, MessageChannel channel) {
            final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
            final StompCommand command = headerAccessor.getCommand();
    
            LOGGER.info("Outbound channel preSend (" + command + ")...");
    
            if (command != null) {
    
                switch (command) {
    
                    case CONNECTED:
                        final StompHeaderAccessor accessor = StompHeaderAccessor.create(headerAccessor.getCommand());
                        accessor.setSessionId(headerAccessor.getSessionId());
                        @SuppressWarnings("unchecked")
                        final MultiValueMap<String, String> nativeHeaders = (MultiValueMap<String, String>) headerAccessor.getHeader(StompHeaderAccessor.NATIVE_HEADERS);
                        accessor.addNativeHeaders(nativeHeaders);
    
                        // add custom headers
                        accessor.addNativeHeader("CUSTOM01", "CUSTOM01");
    
                        return MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
                    default:
                        break;
                }
            }
    
            return message;
        }
    }
    

    这基本上是拦截服务器中的出站消息,如果消息是 CONNECTED ,它将添加一些自定义标题(是的,我最初尝试添加body,但出于测试目的,我暂时坚持使用标题)。

    但是,此方法可以拦截许多STOMP命令,除了 有联系的

    然后我再次提到 STOMP Protocol Spec

    因此,我们似乎无法截获信息,除非 SEND , MESSAGE & ERROR

    我之所以尝试这样做,是为了在连接的每个客户机和服务器之间共享一些公共机密,其中机密由服务器确定。仍在寻求这样的实施。