当我尝试在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)
答案 0 :(得分:5)
您正在尝试订阅user destination,因此必须对用户进行身份验证。
如果这是想要订阅该主题的匿名用户,answer to this question会有所帮助。
您必须为用户分配匿名身份证明,有两种选择:
配置一个覆盖DefaultHandshakeHandler
的{{1}}子类,并为每个WebSocketSession指定某种身份。
WebSocket会话将依赖于握手HTTP请求中determineUser
返回的值。你可以有一个servlet Filter包装HttpServletRequest并决定从该方法返回什么。或者,如果您正在使用具有AnonymousAuthenticationFilter的Spring Security,请覆盖其HttpServletRequest.getUserPrincipal
方法。