大家好我正在尝试向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();
}
}
我没有在控制台中出现任何错误。上述代码适用于网络浏览器。
答案 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” —用于从服务器端应用程序代码中将消息发送到消息代理。
客户端连接到“ http://localhost:8080/portfolio”,一旦建立WebSocket连接,STOMP帧就开始在其上流动。 (在您的情况下: Registry.addEndpoint(“ / hello”)。withSockJS(),您使用“ hello”,在文档中使用“ portfolio”。)
客户端发送带有目标标头“ / topic / hello”的SUBSCRIBE帧。收到并解码后,该消息将发送到“ clientInboundChannel”,然后路由到存储客户端订阅的消息代理。 (这是订阅WebSocket的UI,您在这里没有关于它的代码。可以。)
客户端将SEND帧发送到“ / app / hello”。 “ / app”前缀有助于将其路由到带注释的控制器。除去“ / app”前缀后,目标的其余“ / hello”部分将映射到GreetingController中的@MessageMapping方法。 (在您的代码中:@MessageMapping(“ / hello”)将收到该框架。)
从GreetingController返回的值将转换为带有有效负载的Spring消息,该消息基于返回值和默认目标标头“ / topic / hello”(从输入目标派生,用“ / app”替换为“/话题”)。结果消息将发送到“ brokerChannel”并由消息代理处理。 (因此,当您尝试将数据放入服务器中的WebSocket时:messageSender.convertAndSend(“ / app / hello”,mess);应该更改为messageSender.convertAndSend(“ / topic / hello”,mess),因为它已经在服务器中,我们不需要目的地前缀,但是我们需要代理前缀。)
消息代理找到所有匹配的订阅者,并通过“ clientOutboundChannel”向每个订阅者发送一个MESSAGE帧,消息从此处被编码为STOMP帧并通过WebSocket连接发送。