2016-04-14 34 views
0

Spring websocketでクライアントからサーバーにメッセージを送信しようとすると問題が発生します。 サーバー上にWebsocketを設定し、コントローラ上に@Messageを作成しました。 クライアントからのデータをjavascript経由で送信します。 それはちょうど、時々動作しますが、時にはそれが失敗すると、サーバー上のメッセージを投げる:MissingSessionUserException:メッセージではありません "ユーザー" ヘッダSpring websocket MissingSessionUserException:メッセージに「user」ヘッダーがありません

Here're私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("/"); 
    } 
} 

Here're私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")); 
     } 
    } 
} 

Here're私の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); 
    } 
}); 

Here're私のサーバーのエラーログ:

[2016 Apr 14 - 02:13:19] ERROR: [org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler] - Unhandled exception org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message at org.springframework.messaging.simp.annotation.support.PrincipalMethodArgumentResolver.resolveArgument(PrincipalMethodArgumentResolver.java:42) at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:139) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:108) at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:490) at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:497) at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:87) at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:451) at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:389) at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

答えて

3

あなたはユーザが認証されなければならないuser destinationに加入しようとしています。

トピックに登録したい匿名ユーザーの場合は、answer to this questionが役立ちます。

  1. 設定determineUserをオーバーライドし、すべてのWebSocketSessionにアイデンティティのいくつかの種類を割り当てDefaultHandshakeHandlerのサブクラス:

    あなたは、匿名ユーザーに特定し、二つのオプションがあります割り当てる必要があります。

  2. WebSocketセッションは、ハンドシェイクHTTP要求でHttpServletRequest.getUserPrincipalから返された値に戻ります。あなたはサーブレットフィルターを持つことができます。フィルターはHttpServletRequestをラップし、そのメソッドから返すものを決定します。または、AnonymousAuthenticationFilterを持つSpring Securityを使用している場合は、createAuthenticationメソッドをオーバーライドします。

+1

@Stanleyに感謝します。 私は長い時間前に自分の問題を解決しました。それはあなたの提案と同じです。私のような他の人にも役立つでしょう。 以前は、クライアントがサーバーに送信する前にネットワーク上のヘッダーをチェックしていましたが、ユーザー認証が不足しています。その後、私はちょうどクライアントがサーバーに送信する前にユーザー認証を追加し、正常に動作します。 –

関連する問題