2014-07-15 71 views
0

我通過SockJS通過STOMP連接到我的Spring後端。一切工作正常,配置適用於所有瀏覽器等。但是,我找不到發送初始消息的方式。該方案將是如下:如何在連接事件(SockJS,STOMP,Spring)上發送消息?

  1. 客戶端連接到的話題
 

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

  1. 我想向客戶端發送一個來自後端的自動回覆(在連接事件上),這樣我就可以爲他提供一些數據集(例如re不需要他(客戶端)發送GET請求(或任何其他)。總而言之,我只是想在他連接之後通過SimMessagingTemplate對象向他發送關於該主題的消息。

通常我會按照以下方法進行操作,例如:在REST控制器中,當模板已經自動佈線時:

 

    @Autowired 
    private SimpMessagingTemplate template; 
    ... 
    template.convertAndSend(TOPIC, new Message("it works!")); 

如何在連接事件中實現此目的?

UPDATE

我設法使它工作。不過,我仍然對配置感到困惑。我將在此顯示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); 
}); 

爪哇部分

@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

你不能做到這一點上connect,但是@SubscribeMapping做的東西,在這種情況下。

你只需要標記與註釋的服務方法,它返回一個結果給subscribe功能。

從春季參考手冊:

的@SubscribeMapping註釋也可以用來映射訂閱請求到@Controller方法。它在方法級別上受支持,但也可以與類型級別的@MessageMapping註釋組合,該註釋表示跨同一控制器內的所有消息處理方法的共享映射。

缺省情況下從@SubscribeMapping方法返回值被直接返回到連接的客戶端作爲消息發送和不通過代理。這對實現請求 - 回覆消息交互很有用;例如,在應用程序UI初始化時獲取應用程序數據。或者,可以使用@SendTo對@SubscribeMapping方法進行註釋,在這種情況下,將使用指定的目標目標將結果消息發送到「brokerChannel」。

UPDATE

參照這個例子:https://github.com/revelfire/spring4Test如何會是這樣可能中的index.html的線24被調用時發送任何東西:stompClient.subscribe('/用戶/隊列?/插座/響應......從春天控制器

嗯,是這樣的:

@SubscribeMapping("/queue/socket/responses") 
public List<Employee> list() { 
    return getEmployees(); 
} 

Stomp客戶端部分保持不變。

+0

我怎樣才能做到這一點?鑑於上面的代碼,我無法自動實現這一點。我是否需要運行一個額外的調用(stompClient.send(「/ app/myEndpoint/loadData」,...))來獲取初始消息?或者是否有任何可能的方法來捕捉連接(恰恰是第一個js stompClient.subscribe函數)?我想這是可能的,因爲你寫道,它可以返回到訂閱功能..無論如何,我找不到一種方法去進入這個特定的映射。 –

+0

你不介意tou顯示你的'/ myEndpoint'嗎? –

+0

Artem,我應該分享哪一部分代碼?據我所知,當我用@SubscribeMapping(「/ topic/notify」)創建@Controller註釋的方法時,我應該能夠攔截stompClient.subscribe事件。請讓我分享哪些元素,並將其放在上面的問題主體中。 –

2

如果你只是想在連接時將消息發送到客戶端,使用適當的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 
    } 
}