java - 如何从外部客户端订阅 Spring WebSocket 消息代理?

标签 java spring-boot spring-websocket

我已经使用 Spring Boot 成功实现了一个简单的 websockets 应用程序 tutorial作为指导。应用程序可以成功连接到 STOMP 端点、订阅主题并获取响应。

为了跟上这种微服务趋势,我一直在尝试将客户端置于 Spring Boot 应用程序之外。我可以使用 http://localhost:8080/delivery-ws 成功连接到 STOMP 端点但是,我无法使用 http://localhost:8080/topic/openDeliveries 订阅并从 Spring Boot 应用程序获取更新正如预期的那样。

有什么办法可以订阅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>

最佳答案

您需要更改您尝试订阅的网址。像这样的事情:

stompClient.subscribe('/topic/openDeliveries', function(deliveryList) {
      console.log('in callback for opendelivery topic');
      showDeliveries(deliveryList);
});

一旦连接到套接字端点,就不需要在订阅中定义主机和端口。

关于java - 如何从外部客户端订阅 Spring WebSocket 消息代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38274834/

相关文章:

Spring 4 websocket + stomp + rabbitmq 和集群

java - 自定义@RequestParam返回消息和条件参数

java - 设置 header 网络套接字?

java - 如何使用 JPA 运行 "SET SQL_SAFE_UPDATES = 0"等查询

java - VSCode 中的错误 "The filename, directory name, or volume label syntax is incorrect"

Spring STOMP 配置相互认证 wss/ssl

java - 将程序打包为 jar 后文件输出发生变化

java - JSON服务器生成JSON(java语言)

spring-boot - 使用Kotlin和Gradle时如何将额外的spring-configuration-metadata.json与kapt合并?

spring-boot - Spring微服务之间共享Websocket session