我通过SOMJS通过STOMP连接到我的Spring后端。一切正常,配置适用于所有浏览器等。但是,我找不到发送初始消息的方法。方案如下:
function connect() { var socket = new SockJS('http://localhost:8080/myEndpoint'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/notify', function(message){ showMessage(JSON.parse(message.body).content); }); }); }
并且后端配置看起来或多或少像这样:
@Configuration @EnableWebSocketMessageBroker public class WebSocketAppConfig extends AbstractWebSocketMessageBrokerConfigurer { ... @Override public void registerStompEndpoints(final StompEndpointRegistry registry) { registry.addEndpoint("/myEndpoint").withSockJS(); }
通常我会按照以下方式进行,例如:在REST控制器中,当模板已经自动装配时:
@Autowired private SimpMessagingTemplate template; ... template.convertAndSend(TOPIC, new Message("it works!"));
如何在连接事件中实现此目的?
更新
我设法让它发挥作用。但是,我仍然对配置有点困惑。我将在这里显示2个配置如何发送初始消息:
1)第一个解决方案
JS部分
stompClient.subscribe('/app/pending', function(message){
showMessage(JSON.parse(message.body).content);
});
stompClient.subscribe('/topic/incoming', function(message){
showMessage(JSON.parse(message.body).content);
});
Java部分
@Controller
public class WebSocketBusController {
@SubscribeMapping("/pending")
配置
@Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
......和其他电话
template.convertAndSend("/topic/incoming", outgoingMessage);
2)第二个解决方案
JS部分
stompClient.subscribe('/topic/incoming', function(message){
showMessage(JSON.parse(message.body).content);
})
Java部分
@Controller
public class WebSocketBusController {
@SubscribeMapping("/topic/incoming")
配置
@Override
public void configureMessageBroker(final MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
// NO APPLICATION PREFIX HERE
}
......和其他电话
template.convertAndSend("/topic/incoming", outgoingMessage);
内容:
第一种情况使用了两个订阅 - 这是我想要避免的,并认为只能用一个订阅。
然而,第二个没有申请前缀。但至少我可以有一个订阅来听取提供的主题以及发送初始消息。
答案 0 :(得分:3)
如果您只想在连接时向客户端发送消息,请使用适当的ApplicationListener:
@Component
public class StompConnectedEvent implements ApplicationListener<SessionConnectedEvent> {
private static final Logger log = Logger.getLogger(StompConnectedEvent.class);
@Autowired
private Controller controller;
@Override
public void onApplicationEvent(SessionConnectedEvent event) {
log.debug("Client connected.");
// you can use a controller to send your msg here
}
}
答案 1 :(得分:0)
您无法在connect
上执行该操作,但@SubscribeMapping
会执行此类操作。
您只需要使用该注释标记服务方法,并将结果返回给subscribe
函数。
从Spring参考手册:
@SubscribeMapping注释也可用于将订阅请求映射到@Controller方法。它在方法级别上受支持,但也可以与类型级别@MessageMapping注释结合使用,该注释表示同一控制器中所有消息处理方法的共享映射。
默认情况下,@ SubsscribeMapping方法的返回值作为消息直接发送回连接的客户端,并且不通过代理。这对于实现请求 - 回复消息交互很有用;例如,在初始化应用程序UI时获取应用程序数据。或者可以使用@SendTo注释@SubscribeMapping方法,在这种情况下,生成的消息将被发送到&#34; brokerChannel&#34;使用指定的目标目的地。
<强>更新强>
参考这个例子:https://github.com/revelfire/spring4Test当调用index.html的第24行时,如何发送任何内容:stompClient.subscribe(&#39; / user / queue / socket / responses&# 39; ......来自弹簧控制器?
好吧,看起来像这样:
@SubscribeMapping("/queue/socket/responses")
public List<Employee> list() {
return getEmployees();
}
Stomp客户端部分保持不变。