Spring Websocket回复用户消息流程

Spring Websocket Reply To User Message Flow

我正在尝试使用 spring-websocket 在用户之间发送私人消息。

我发现了以下内容:

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

其中包括:

发送回复给用户

@Controller
public class GreetingController {

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

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

}

以上似乎暗示发送到“/user/{username}/queue/greetings”的消息将在将 return 值发送到指定用户之前调用 greet 方法。

当我向此目的地发送消息时,它会直接发送给用户,而无需通过 greet 控制器方法进行处理。

我是否正确理解了预期流程?如果我不这样做,我需要做什么才能在将消息发送给用户之前使用控制器方法对其进行处理。

我能找到的一切都指向 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);

}

应用到我的场景会变成:

@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);
  }

}

@SendToUser 注释定义方法的 return 值应发送到前缀为 /user/{username} 的用户目的地,其中用户名是从 headers 正在处理的输入消息(当前用户)。

在 Spring 4.2 中你可以在 @SendTo 中使用占位符(只有目标变量占位符,见 SPR-12170),如果你将用户名作为目标变量传递,你可以做类似的事情这个:

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

此方法在内部使用 SimpMessagingTemplate,因此如果您使用的是 4.2 之前的版本,则对动态目标使用 SimpMessagingTemplate 没有任何问题:

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