How to add event listeners to Vue socket cluster client in a method?

612 Views Asked by At

I try to add a Vue socket cluster connection inside a method rather than at startup. Here is the result of my research. I see several issues. I added the connection directives inside a method called connect(), this method is called by a click from another component. It works, but then, there is an issue with the event listeners. I have tried to add one using Vue.extend to add it to the connection but it blocks any update made on the component. For example, in my code, I added this.msg="this is a test"; but the msg mutation does not work after I added the event listeners.

I have also tried to add the event listeners using this.$options.SeoScanEvents.nameofwebsocketmessage as an alternative to vue.extend but it does work at all.

This code uses the structure of the dummy vue.js application. So if you want to replicate this issue, you just have to install the dummy structure of a VUEJS app, then replace main.js and HelloWorld.vue with the following. Then you need the default server.js and worker.js from socketcluster.io to run on port 8000. It should return a random number.

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import VueSocketCluster from 'vue-socket-cluster'

Vue.config.productionTip = false

/* eslint-disable no-new */
const vm = new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',

  SeoScanEvents:{
    connect: function(data){ // I added it here to see in vm object if I could replicate the property. For sure it does not work because it comes before the connection directives.
        console.log('socket connected')
        console.log(data)
    },

    // ['error','connect','disconnect','connectAbort','connecting', etc ...] See socket cluster docs
    error () {
        //An error occurred on the connection name echo
    },
    connecting () {

    },
    // ...
    // for hyphen separated events such as 'custom-error' use ...
    customError () {

    },/*
    random(data){
      console.log(data)
    }*/
  },
methods:{
  connect(){

    Vue.use(VueSocketCluster, {
      connections: [{
            name: 'SeoScan', 
            hostname: 'localhost',
            secure: false,
            port: 8000,
            rejectUnauthorized: false
      }]
    })


    var Comp = Vue.extend({
      SeoScanEvents:{
        random: function(data){
          console.log(data);
        }
      }
    });

 new Comp().$mount('#app'); // this works but it blocks any updates on my vue component for example the this.msg=... below does not work
console.log(this);

/*
this.$options.SeoScanEvents.random = function random(data) { // this does not work
  console.log(data) // should show the random numbers generated by the default server config file from Socket Cluster
} 
*/

  }
}
});

HelloWorld.vue

<template ref="gogo">
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2 @click="submit1">Essential Links</h2>
    <ul>
      <li>
        <a
          href="https://vuejs.org"
          target="_blank"
        >
          Core Docs
        </a>
      </li>
      <li>
        <a
          href="https://forum.vuejs.org"
          target="_blank"
        >
          Forum
        </a>
      </li>
      <li>
        <a
          href="https://chat.vuejs.org"
          target="_blank"
        >
          Community Chat
        </a>
      </li>
      <li>
        <a
          href="https://twitter.com/vuejs"
          target="_blank"
        >
          Twitter
        </a>
      </li>
      <br>
      <li>
        <a
          href="http://vuejs-templates.github.io/webpack/"
          target="_blank"
        >
          Docs for This Template
        </a>
      </li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li>
        <a
          href="http://router.vuejs.org/"
          target="_blank"
        >
          vue-router
        </a>
      </li>
      <li>
        <a
          href="http://vuex.vuejs.org/"
          target="_blank"
        >
          vuex
        </a>
      </li>
      <li>
        <a
          href="http://vue-loader.vuejs.org/"
          target="_blank"
        >
          vue-loader
        </a>
      </li>
      <li>
        <a
          href="https://github.com/vuejs/awesome-vue"
          target="_blank"
        >
          awesome-vue
        </a>
      </li>
    </ul>
  </div>
</template>

<script>
var message = 'Vue.js is rad';

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: message,
      myArray: []
    }
  },
  methods:{
    submit1(){
      console.log(this);
      this.msg="this is a test"; // this does not work when I add the event listeners using Vue.extend
      console.log(new Date())
      this.$root.connect(); // trigger Vue Socket cluster connection

    }
  },
  mounted(){

  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
1

There are 1 best solutions below

0
On

The right solution would be to

  1. Create a vue.use for the connection with autoConnect: false below import VueSocketCluster from 'vue-socket-cluster'
> Vue.use(VueSocketCluster, {
>         connections: [{
>           name: 'SeoScan', // Each connection object must have a name and the name must be unique in the array
>           hostname: 'localhost',
>           secure: false,
>           port: 5128,
>           rejectUnauthorized: false,
>           autoConnect: false
>         }]
>       });
  1. then, add in your components (here HelloWorld.vue) the event listeners under export default

    SeoScanEvents: { connect: function (data) { console.log('socket connected') console.log(data) }, random (data) { console.log(data) } }

  2. In the method submit1 rather than calling the method connect from the root, call the method that will start the connection: this.$SeoScanClient.connect();