如何从外部客户端订阅 spring websocket 消息代理?
How to subscribe to a spring websocket message broker from an external client?
我已经使用此 tutorial 作为指南,通过 Spring 引导成功实现了一个简单的 websockets 应用程序。该应用程序可以成功连接到 STOMP 端点,订阅主题并获得响应。
为了让一切都跟上这种微服务趋势,我一直在尝试让客户端在 spring 启动应用程序之外。我可以使用 http://localhost:8080/delivery-ws
成功连接到 STOMP 端点,但是我无法使用 http://localhost:8080/topic/openDeliveries
从 spring 启动应用程序订阅和获取更新,这与预期的一样。
有什么办法可以对外订阅topic/openDeliveries
吗?
WebSocketConfig.java
@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("/delivery-ws").setAllowedOrigins("*").withSockJS();
}
}
DeliveryController.java
@Controller
@RequestMapping("deliveries")
public class DeliveryController {
private DeliveryRepository repository;
SimpMessagingTemplate template;
@Autowired
public DeliveryController(DeliveryRepository repository, SimpMessagingTemplate template) {
this.repository = repository;
this.template = template;
}
public void updateListandBroadcast() {
System.out.println("in update and broadcast");
template.convertAndSend("/topic/openDeliveries", getOpenDeliveries());
}
public List<Delivery> getOpenDeliveries() {
return repository.findByDeliveredFalse();
}
@RequestMapping(value = "/new", method = RequestMethod.POST)
public @ResponseBody Delivery newDelivery(@RequestBody Delivery delivery) {
Delivery d = repository.save(delivery);
updateListandBroadcast();
return d;
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public @ResponseBody void delete(@PathVariable String id) {
repository.delete(Long.parseLong(id));
updateListandBroadcast();
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Active Deliveries</title>
<script src="sockjs-0.3.4.js"></script>
<script src="stomp.js"></script>
<script src="jquery-3.0.0.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS('http://localhost:8080/delivery-ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('http://localhost:8080/openDeliveries', function(deliveryList) {
console.log('in callback for opendelivery topic');
showDeliveries(deliveryList);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function showDeliveries(list) {
console.log('in show deliveries');
var response = document.getElementById('response');
response.innerHTML = list.body;
}
</script>
</head>
<body onload="disconnect()">
<h1>Deliveries</h1>
<noscript>
<h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
Javascript and reload this page!</h2>
</noscript>
<div>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div id="conversationDiv">
<p id="response"></p>
<table id="data-table"></table>
</div>
</div>
</body>
</html>
您需要更改您尝试订阅的 url。像这样:
stompClient.subscribe('/topic/openDeliveries', function(deliveryList) {
console.log('in callback for opendelivery topic');
showDeliveries(deliveryList);
});
连接到套接字端点后,无需在订阅中定义主机和端口。
我已经使用此 tutorial 作为指南,通过 Spring 引导成功实现了一个简单的 websockets 应用程序。该应用程序可以成功连接到 STOMP 端点,订阅主题并获得响应。
为了让一切都跟上这种微服务趋势,我一直在尝试让客户端在 spring 启动应用程序之外。我可以使用 http://localhost:8080/delivery-ws
成功连接到 STOMP 端点,但是我无法使用 http://localhost:8080/topic/openDeliveries
从 spring 启动应用程序订阅和获取更新,这与预期的一样。
有什么办法可以对外订阅topic/openDeliveries
吗?
WebSocketConfig.java
@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("/delivery-ws").setAllowedOrigins("*").withSockJS();
}
}
DeliveryController.java
@Controller
@RequestMapping("deliveries")
public class DeliveryController {
private DeliveryRepository repository;
SimpMessagingTemplate template;
@Autowired
public DeliveryController(DeliveryRepository repository, SimpMessagingTemplate template) {
this.repository = repository;
this.template = template;
}
public void updateListandBroadcast() {
System.out.println("in update and broadcast");
template.convertAndSend("/topic/openDeliveries", getOpenDeliveries());
}
public List<Delivery> getOpenDeliveries() {
return repository.findByDeliveredFalse();
}
@RequestMapping(value = "/new", method = RequestMethod.POST)
public @ResponseBody Delivery newDelivery(@RequestBody Delivery delivery) {
Delivery d = repository.save(delivery);
updateListandBroadcast();
return d;
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public @ResponseBody void delete(@PathVariable String id) {
repository.delete(Long.parseLong(id));
updateListandBroadcast();
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Active Deliveries</title>
<script src="sockjs-0.3.4.js"></script>
<script src="stomp.js"></script>
<script src="jquery-3.0.0.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS('http://localhost:8080/delivery-ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('http://localhost:8080/openDeliveries', function(deliveryList) {
console.log('in callback for opendelivery topic');
showDeliveries(deliveryList);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function showDeliveries(list) {
console.log('in show deliveries');
var response = document.getElementById('response');
response.innerHTML = list.body;
}
</script>
</head>
<body onload="disconnect()">
<h1>Deliveries</h1>
<noscript>
<h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
Javascript and reload this page!</h2>
</noscript>
<div>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div id="conversationDiv">
<p id="response"></p>
<table id="data-table"></table>
</div>
</div>
</body>
</html>
您需要更改您尝试订阅的 url。像这样:
stompClient.subscribe('/topic/openDeliveries', function(deliveryList) {
console.log('in callback for opendelivery topic');
showDeliveries(deliveryList);
});
连接到套接字端点后,无需在订阅中定义主机和端口。