Spring websocket遇到"忽略消息,没有可用的主要信息"错误

时间:2014-07-24 04:18:43

标签: java spring websocket

我正在使用spring 4 websocket进行特定于用户的主题订阅,而我的应用程序并不依赖于安全机制,握手失败,因为主体为空,我尝试要扩展 DefaultHandshakeHandler 并覆盖 determineUser 受保护的方法,我是否需要填充主体对象以及如何填充?任何帮助都将非常感激。

配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello").setHandshakeHandler(customHandshakeHandler()).withSockJS();
    }

    @Bean
    public CustomHandshakeHandler customHandshakeHandler() {
        return new CustomHandshakeHandler();
    }

}

CustomHandshakeHandler.java

public class CustomHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, 
            Map<String, Object> attributes) {
        return request.getPrincipal(); // return null here, how to populate principal???
    }

}

服务器端:

template.convertAndSendToUser(username, "/greetings", new Greeting("Hello World!"));

客户方:

function connect(username) {
    var socket = new SockJS('http://localhost:8081/websocket/hello');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function(frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        //stompClient.subscribe('/topic/greetings', function(greeting){
        stompClient.subscribe('/user/' + username + '/greetings', function(greeting){
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

错误日志:

ERROR: org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession - Closing due to transport error for SockJS session id=zw90o_sm
ERROR: org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator - Transport error for SockJS session id=zw90o_sm
java.lang.IllegalArgumentException: No 'javax.websocket.server.ServerContainer' ServletContext attribute. Are you running in a Servlet container that supports JSR-356?
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getContainer(AbstractStandardUpgradeStrategy.java:68)
    at org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy.getContainer(TomcatRequestUpgradeStrategy.java:85)
    at org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy.getContainer(TomcatRequestUpgradeStrategy.java:47)
    at org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getSupportedExtensions(AbstractStandardUpgradeStrategy.java:88)
    at org.springframework.web.socket.server.support.DefaultHandshakeHandler.doHandshake(DefaultHandshakeHandler.java:206)
    at org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler.handleRequest(WebSocketTransportHandler.java:83)
    at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:254)
    at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:317)
    at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:695)
Jul 24, 2014 11:55:21 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/websocket] threw exception [Request processing failed; nested exception is org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=http://localhost:8081/websocket/hello/474/zw90o_sm/websocket; nested exception is org.springframework.web.socket.sockjs.SockJsTransportFailureException: WebSocket handshake failure; nested exception is java.lang.IllegalArgumentException: No 'javax.websocket.server.ServerContainer' ServletContext attribute. Are you running in a Servlet container that supports JSR-356?] with root cause
java.lang.IllegalArgumentException: No 'javax.websocket.server.ServerContainer' ServletContext attribute. Are you running in a Servlet container that supports JSR-356?
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getContainer(AbstractStandardUpgradeStrategy.java:68)
    at org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy.getContainer(TomcatRequestUpgradeStrategy.java:85)
    at org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy.getContainer(TomcatRequestUpgradeStrategy.java:47)
    at org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getSupportedExtensions(AbstractStandardUpgradeStrategy.java:88)
    at org.springframework.web.socket.server.support.DefaultHandshakeHandler.doHandshake(DefaultHandshakeHandler.java:206)
    at org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler.handleRequest(WebSocketTransportHandler.java:83)
    at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:254)
    at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:317)
    at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:695)
ERROR: org.springframework.messaging.simp.user.DefaultUserDestinationResolver - Ignoring message, no principal info available

1 个答案:

答案 0 :(得分:1)

您问的是一件事,但您发布的错误日志显示了另一个问题:

  

java.lang.IllegalArgumentException:No&#39; javax.websocket.server.ServerContainer&#39; ServletContext属性。您是否在支持JSR-356的Servlet容器中运行?

您是否在支持JSR-356的servlet容器中运行?如果您在Tomcat上运行,则至少需要Tomcat 7.0.47。对于其他servlet容器,您必须检查所需的版本。来自Spring docs

  

Spring Framework提供了一个WebSocket API,旨在适应各种WebSocket引擎。例如,它运行在JSR-356运行时,例如Tomcat(7.0.47 +),GlassFish(4.0+)和WildFly(8.0+),但也可以适应其他WebSocket运行时,例如Jetty(9.1+)本机WebSocket支持