使用Vue.js实现Spring Stomp WebSocket。

11

我正在尝试在Vue中使用Spring Websockets (STOMP),但无法弄清楚如何实现,或者它是否可能。 我的Websockets可以通过纯JS工作,但是当我尝试使用Vue时就会卡住。 这是我的Vue代码:

var app = new Vue({
el: '#app',
data: {
    stompClient: null,
    gold: 0
},
methods: {
    sendEvent: function () {
        this.stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
    }
},
created: function () {
    this.stompClient = Stomp.over(new SockJS('/gs-guide-websocket'));
    this.stompClient.connect()
    this.stompClient.subscribe('/topic/greetings', function (greeting) {
        console.log(JSON.parse(greeting.body).content);
    });
},

我的connect和send函数工作正常,我可以在后端看到消息,但问题在于subscribe函数。它需要一个回调函数,但这个函数从未触发过。我还尝试过在Vue中创建一个方法并调用它。

this.stompClient.subscribe('/topic/greetings', vueFunc())

但这也行不通。我在https://github.com/FlySkyBear/vue-stomp找到了一些库,但我无法弄清如何使用它,而且看起来很混乱。我宁愿使用普通JS。

有人有解决方案吗?谢谢

2个回答

28

这是一个使用Spring Boot Websocket(STOMP)和Vue CLI的工作示例。 (更详细的描述在这里http://kojotdev.com/2019/07/using-spring-websocket-stomp-application-with-vue-js/

  1. https://spring.io/guides/gs/messaging-stomp-websocket/下载Spring Boot演示。
  2. WebSocketConfig中添加允许的来源

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/gs-guide-websocket")
            .setAllowedOrigins("http://localhost:8081")
            .withSockJS();
}
  • 运行项目
  • 现在启动Vue CLI项目并执行以下操作:

    1. 安装SockJS npm install sockjs-client
    2. 安装STOMP npm install webstomp-client
    3. 我使用了Bootstrap类,所以你需要npm install bootstrap@3只是为了布局

    添加 .vue 组件:

    <template>
        <div>
            <div id="main-content" class="container">
                <div class="row">
                    <div class="col-md-6">
                        <form class="form-inline">
                            <div class="form-group">
                                <label for="connect">WebSocket connection:</label>
                                <button id="connect" class="btn btn-default" type="submit" :disabled="connected == true" @click.prevent="connect">Connect</button>
                                <button id="disconnect" class="btn btn-default" type="submit" :disabled="connected == false" @click.prevent="disconnect">Disconnect
                                </button>
                            </div>
                        </form>
                    </div>
                    <div class="col-md-6">
                        <form class="form-inline">
                            <div class="form-group">
                                <label for="name">What is your name?</label>
                                <input type="text" id="name" class="form-control" v-model="send_message" placeholder="Your name here...">
                            </div>
                            <button id="send" class="btn btn-default" type="submit" @click.prevent="send">Send</button>
                        </form>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-12">
                        <table id="conversation" class="table table-striped">
                            <thead>
                                <tr>
                                    <th>Greetings</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr v-for="item in received_messages" :key="item">
                                    <td>{{ item }}</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
    import SockJS from "sockjs-client";
    import Stomp from "webstomp-client";
    
    export default {
      name: "websocketdemo",
      data() {
        return {
          received_messages: [],
          send_message: null,
          connected: false
        };
      },
      methods: {
        send() {
          console.log("Send message:" + this.send_message);
          if (this.stompClient && this.stompClient.connected) {
            const msg = { name: this.send_message };
            this.stompClient.send("/app/hello", JSON.stringify(msg), {});
          }
        },
        connect() {
          this.socket = new SockJS("http://localhost:8080/gs-guide-websocket");
          this.stompClient = Stomp.over(this.socket);
          this.stompClient.connect(
            {},
            frame => {
              this.connected = true;
              console.log(frame);
              this.stompClient.subscribe("/topic/greetings", tick => {
                console.log(tick);
                this.received_messages.push(JSON.parse(tick.body).content);
              });
            },
            error => {
              console.log(error);
              this.connected = false;
            }
          );
        },
        disconnect() {
          if (this.stompClient) {
            this.stompClient.disconnect();
          }
          this.connected = false;
        },
        tickleConnection() {
          this.connected ? this.disconnect() : this.connect();
        }
      },
      mounted() {
        // this.connect();
      }
    };
    </script>
    
    <style scoped>
    
    </style>
    

    运行项目并进行测试,它应默认在8081端口启动。


    5
    你是我的英雄。难以置信的是,标准教程中没有提到.setAllowedOrigins("*")。谢谢! - Maurice Müller
    任何人都在关注这个答案吗?Webstomp-client的send()参数顺序与Stompjs不同,尽管两者在教程中可以互换使用。Webstomp-client的send(dest, msg, headers)和Stompjs的send(dest, headers, msg)以及类似的函数。 - Shubham Debnath

    1

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接