SimpMessagingTemplate不在spring boot中发送消息

时间:2016-04-06 16:04:51

标签: java spring spring-boot stomp

大家好我正在尝试向Stomp Endpoints发送消息,但我没有得到任何消息。我正在使用弹簧启动,下面是我的课程

@Controller
public class GreetingController {

  @MessageMapping("/hello")
  @SendTo("/topic/greetings")
  public Greeting greeting(HelloMessage message) throws Exception {
    System.out.println(message.getName());
    Thread.sleep(13000); // simulated delay
    return new Greeting("Hello, " + message.getName() + "!");
  }

}

@Controller                                                
public class Testcont {

  @Autowired
  private SimpMessagingTemplate messageSender;

  @RequestMapping(value="/Users/get",method=RequestMethod.POST)
  @ResponseBody
  public String getUser(@RequestParam(value = "userId") String userId, @RequestParam(value = "password") String password, @RequestParam(value="port") String port, HttpServletRequest request) {
    HelloMessage mess=new HelloMessage();
    mess.setName(userId);
    messageSender.convertAndSend("/app/hello",mess);
    return "Success";

}

和我的websocket配置

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/hello").withSockJS();
    }

}

我没有在控制台中出现任何错误。上述代码适用于网络浏览器。

2 个答案:

答案 0 :(得分:6)

SimpMessagingTemplate bean完全适用于Broker部分(AbstractMessageBrokerConfiguration):

@Bean
public SimpMessagingTemplate brokerMessagingTemplate() {
    SimpMessagingTemplate template = new SimpMessagingTemplate(brokerChannel());
    String prefix = getBrokerRegistry().getUserDestinationPrefix();
    if (prefix != null) {
        template.setUserDestinationPrefix(prefix);
    }

由于您不将邮件发送到代理目的地(在您的情况下为/app/),因此AbstractBrokerMessageHandler.checkDestinationPrefix(destination)会忽略此类邮件。

如果您希望通过相同的@MessageMapping处理该内部消息,则应直接使用clientInboundChannel提供的SimpAnnotationMethodMessageHandler

@Bean
public SimpAnnotationMethodMessageHandler simpAnnotationMethodMessageHandler() {
    SimpAnnotationMethodMessageHandler handler = createAnnotationMethodMessageHandler();
    handler.setDestinationPrefixes(getBrokerRegistry().getApplicationDestinationPrefixes());

我猜你可以为SimpMessagingTemplate创建自己的clientInboundChannel实例,类似于brokerMessagingTemplate bean。你会没事的。

答案 1 :(得分:1)

在使用WebSocket时,我遇到相同的问题。这篇文章为时已晚,但是对于寻找答案的人可能有用。

SimpMessagingTemplate->使用“主题”而不是“应用” 所以 messageSender.convertAndSend(“ / topic / hello”,mess);将是一个解决方案。

来自上述WebSocket文档:

“ clientInboundChannel” —用于传递从WebSocket客户端接收到的消息。

“ clientOutboundChannel” —用于将服务器消息发送到WebSocket客户端。

“ brokerChannel” —用于从服务器端应用程序代码中将消息发送到消息代理。

  1. 客户端连接到“ http://localhost:8080/portfolio”,一旦建立WebSocket连接,STOMP帧就开始在其上流动。 (在您的情况下: Registry.addEndpoint(“ / hello”)。withSockJS(),您使用“ hello”,在文档中使用“ portfolio”。)

  2. 客户端发送带有目标标头“ / topic / hello”的SUBSCRIBE帧。收到并解码后,该消息将发送到“ clientInboundChannel”,然后路由到存储客户端订阅的消息代理。 (这是订阅WebSocket的UI,您在这里没有关于它的代码。可以。)

  3. 客户端将SEND帧发送到“ / app / hello”。 “ / app”前缀有助于将其路由到带注释的控制器。除去“ / app”前缀后,目标的其余“ / hello”部分将映射到GreetingController中的@MessageMapping方法。 (在您的代码中:@MessageMapping(“ / hello”)将收到该框架。)

  4. 从GreetingController返回的值将转换为带有有效负载的Spring消息,该消息基于返回值和默认目标标头“ / topic / hello”(从输入目标派生,用“ / app”替换为“/话题”)。结果消息将发送到“ brokerChannel”并由消息代理处理。 (因此,当您尝试将数据放入服务器中的WebSocket时:messageSender.convertAndSend(“ / app / hello”,mess);应该更改为messageSender.convertAndSend(“ / topic / hello”,mess),因为它已经在服务器中,我们不需要目的地前缀,但是我们需要代理前缀。)

  5. 消息代理找到所有匹配的订阅者,并通过“ clientOutboundChannel”向每个订阅者发送一个MESSAGE帧,消息从此处被编码为STOMP帧并通过WebSocket连接发送。