Spring websocket MissingSessionUserException:No" user"消息

时间:2016-04-14 07:15:03

标签: backbone.js websocket stomp spring-websocket

当我尝试在Spring websocket上从客户端向服务器发送消息时,我遇到了问题。 我在服务器上配置Websocket并在控制器上创建@Message。 我通过javascript从客户端发送数据。 它有时会工作,但有时会失败并在服务器上抛出消息: MissingSessionUserException:No" user"消息中的标题

这是我的WebsocketConfig:

public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/connectsocket").withSockJS();
    }
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/");
    }
}

这是我的MessageController:

@RestController
public class MessageController {

    @Autowired
    private SimpMessagingTemplate template;

    @MessageMapping("/websocket/message")
    public synchronized void message(Message<Object> messageObj, 
        WebMessage message, Principal principal) throws Exception {
        if (principal != null) {
            String name = principal.getName();
            template.convertAndSendToUser(name, "/topic/dynamic", new MessagePojo("stage", "value", "message"));
        }
    }
}

这里是我的Javascript-backbonejs代码:

app.Models.WebsocketModel = Backbone.Model.extend({
    fetchData : function() {
        console.log("WebsocketModel: fetchData");
        var socket = new SockJS(url + "/connectsocket");
        var client = Stomp.over(socket);

        var onConnect = function(frame) {
            console.log('Connected: ' + frame);
            client.subscribe("/user/topic/dynamic", function(data) {
                var jsonBody = JSON.parse(data.body);
                console.log(jsonBody);
            });
        };

        client.connect({}, onConnect);

        setInterval(function() {
            client.send("/websocket/message", {}, JSON.stringify({
                "message" : "Hello world!!!",
                "toUser" : "Someone"
            }));
        }, 10000);
    }
});

这是我的服务器错误日志:

  

[2016年4月14日 - 02:13:19]错误:   [org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler]    - 未处理的异常org.springframework.messaging.simp.annotation.support.MissingSessionUserException:   不#34;用户&#34;消息中的标题   org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:42)     在   org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)     在   org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:139)     在   org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:108)     在   org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:490)     在   org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:497)     在   org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:87)     在   org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:451)     在   org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:389)     在   org.springframework.messaging.support.ExecutorSubscribableChannel $ SendTask.run(ExecutorSubscribableChannel.java:135)     在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:617)     在java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:5)

您正在尝试订阅user destination,因此必须对用户进行身份验证。

如果这是想要订阅该主题的匿名用户,answer to this question会有所帮助。

您必须为用户分配匿名身份证明,有两种选择:

  1. 配置一个覆盖DefaultHandshakeHandler的{​​{1}}子类,并为每个WebSocketSession指定某种身份。

  2. WebSocket会话将依赖于握手HTTP请求中determineUser返回的值。你可以有一个servlet Filter包装HttpServletRequest并决定从该方法返回什么。或者,如果您正在使用具有AnonymousAuthenticationFilter的Spring Security,请覆盖其HttpServletRequest.getUserPrincipal方法。