Spring Websocket Reply To User Message Flow

被刻印的时光 ゝ 提交于 2019-12-06 11:53:56

问题


I am trying to send a private message between users using spring-websocket.

I found the following:

https://github.com/rstoyanchev/springx2013-websocket/blob/master/spring-messaging/slides.md

which includes:

Send Reply To User

@Controller
public class GreetingController {

  // Message sent to "/user/{username}/queue/greetings"

  @MessageMapping("/greetings")
  @SendToUser
  public String greet(String greeting) {
      return "[" + getTimestamp() + "]: " + greeting;
  }

}

The above seems to imply that a message sent to "/user/{username}/queue/greetings" will invoke the greet method before sending the return value on to the specified user.

When I send a message to this destination, it gets sent to the directly to the user without being processed by the greet controller method.

Do I understand the expected flow correctly? If I don't, what do I need to do to be able to process the message using a controller method before it's sent to a user.


回答1:


The @SendToUser annotation defines that the return value of the method should be send to a user destination prefixed with /user/{username} where the user name is extracted from the headers of the input message being handled (current user).

In Spring 4.2 you can use placeholders in @SendTo (only destination variable placeholders, see SPR-12170), if you pass the username as a destination variable you could do something like this:

@MessageMapping("/greetings/{u}")
@SendTo("/user/{u}/queue/greetings")
public String greet(String greeting) {
    return "[" + getTimestamp() + "]: " + greeting;
}

This approach uses the SimpMessagingTemplate internally, so if you are using a version previous to 4.2, there's nothing wrong in using the SimpMessagingTemplate for dynamic destinations:

@MessageMapping("/greetings/{username}")
public void greet(@Payload String greeting, @DestinationVariable("username") String username) {
  String message =  "[" + getTimestamp() + "]: " + greeting;
  simpMessagingTemplate.convertAndSend("/user/" + username + "/queue/greetings", message);
}



回答2:


Everything I can find points in the direction of the following pattern found in https://github.com/salmar/spring-websocket-chat :

@MessageMapping("/chat.private.{username}")
public void filterPrivateMessage(@Payload ChatMessage message, @DestinationVariable("username") String username, Principal principal) {

    checkProfanityAndSanitize(message); 
    message.setUsername(principal.getName());
    simpMessagingTemplate.convertAndSend("/user/" + username + "/queue/chat.message", message);

}

Applied to my scenario would become:

@Controller
public class GreetingController {

  // Message sent to "/app/greetings/{username}"

  @MessageMapping("/greetings/{username}")
  public void greet(String greeting) {
      String message =  "[" + getTimestamp() + "]: " + greeting;
      simpMessagingTemplate.convertAndSend("/user/" + username + "/queue/greetings", message);
  }

}


来源:https://stackoverflow.com/questions/30464230/spring-websocket-reply-to-user-message-flow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!