【问题标题】:spring web socket and stomp issuespring web socket和stomp问题
【发布时间】:2016-05-17 06:56:38
【问题描述】:

我有一个基于 Spring 的应用程序,它使用 websocket、stomp.js 和 JPA 来实现持久性。 以下是 websocket 的配置

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        // TODO Auto-generated method stub
        stompEndpointRegistry.addEndpoint("/ws").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

}

控制器是

@Controller
public class HomeController {
    @Autowired private StockService<Stock> stockService;
    @Autowired private SimpMessagingTemplate template; 

      private void updatePriceAndBroadcast() {          
        template.convertAndSend("/topic/price", stockService.getAll());
      }       


      @MessageMapping("/addStock")
      public void addStock(Stock stock) throws Exception {           
          stockService.save(stock);         
          updatePriceAndBroadcast();
      }       


      @RequestMapping(value = "/", method = RequestMethod.GET)
      public String home() {
          updatePriceAndBroadcast();
        return "home";
      }

}

查看为 home.jsp 是

<html>
<head>
    <title>Real time notify example</title>
</head>
<body>
  <h1>Real time notify example</h1>

  <table>
    <thead><tr><th>Code</th><th>Price</th><th>Time</th></tr></thead>
    <tbody id="price"></tbody>
  </table>

  <p class="new">
    Code: <input type="text" class="code"/>
    Price: <input type="text" class="price"/>
    <button class="add">Add</button>
    <button class="remove-all">Remove All</button>
  </p>

  <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
  <script src="/notify/resources/stomp.js"></script>
  <script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
  <script>
    //Create stomp client over sockJS protocol
    var socket = new SockJS("/notify/ws");
    var stompClient = Stomp.over(socket);      

    // Callback function to be called when stomp client is connected to server
    var connectCallback = function() {
      stompClient.subscribe('/topic/price', renderPrice);
    }; 

    // Callback function to be called when stomp client could not connect to server
    var errorCallback = function(error) {
      alert(error.headers.message);
    };

    // Connect to server via websocket
    stompClient.connect("guest", "guest", connectCallback, errorCallback);

    // Register handler for add button
    $(document).ready(function() {
      $('.add').click(function(e){
        e.preventDefault();
        var code = $('.new .code').val();
        var price = Number($('.new .price').val());
        var jsonstr = JSON.stringify({ 'code': code, 'price': price });
        stompClient.send("/app/addStock", {}, jsonstr);
        return false;
      });
    });

    // Register handler for remove all button
    $(document).ready(function() {
      $('.remove-all').click(function(e) {
        e.preventDefault();
        stompClient.send("/app/removeAllStocks");
        return false;
      });
    });
  </script>
</body>
</html>

当我击球时

<button class="add">Add</button>

我得到了已添加项目的列表,但是当我刷新页面或打开新页面时,我没有看到已添加项目的列表,任何人都可以告诉我在哪里进行更改,以便我获得已添加/已保存的列表刷新页面或打开新的浏览器实例后的项目。

应用程序可在 realtimetest

【问题讨论】:

    标签: java spring-mvc stomp spring-websocket


    【解决方案1】:

    在Controller中更改方法为

       /**
       * Serve the main page
       */
      @RequestMapping(value = "/", method = RequestMethod.GET)
      public String home(Model model) {
          model.addAttribute("listOfItems", stockService.getAll());
        return "home";
      }
    

    并在视图方面进行一些更改:

    <h1>Real time notify example</h1>
    
        <table>
            <thead>
                <tr>
                    <th>Code</th>
                    <th>Price</th>
                    <th>Time</th>
                </tr>
            </thead>
            <tbody id="price">
                <c:forEach items="${listOfItems }" var="item">
                    <tr>
                        <td>${item.code }</td>
                        <td>${item.price }</td>
    
                    </tr>
                </c:forEach>
            </tbody>
        </table>
    

    最后将所有其他 javascript 内容保持原样。

    希望这是有意义的并修复 丑陋的错误。

    工作示例在real-time_test

    【讨论】:

    • 我一直在努力解决上述问题,现在我找到了解决方案。我想确保这是让事情按照问题要求的方式工作的正确方法吗?我将我的答案摆在你面前(社区),请查看并做出如果需要进行更改以使此答案尽可能有用。 提前致谢!