npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wynnyo/vue-signalr

v1.0.1

Published

Signalr client for vue js

Downloads

4

Readme

vue-signalr

BLOG

Thanks @latelierco/vue-signalr (github.com)

关于项目说明

个人在使用 @latelierco/vue-signalr 时发现了一些问题, 于是 clone 下项目进行了一些改进

问题的复现

  • 在 main.js 下

    import VueSignalR from '@latelierco/vue-signal'
    Vue.use(VueSignalR, process.env.VUE_APP_BASE_API + 'hub/message')
  • 在 app.vue

    created() {
      // 启动
      this.$socket.start()
    	// 监听 init 事件
      this.$socket.on('init', () => {
      	console.log('init')
      })
    	// 监听 reconnect 事件
      this.$socket.on('reconnect', () => {
      	console.log('reconnect')
      })
    	// 输出 $socket
      console.log(this.$socket)
    },
    sockets: {
      // 监听 ReceiveMessage 事件
    	ReceiveMessage(data) {
      	console.log(data)
      }
    }
  • 当我编辑多次 app.vue 然后保存

    image-20201221112232103

  • 这时我断开后端

    image-20201221112447020

  • 查看 $socket, 发现 event 注册了多次

    image-20201221112816365

分析原因

热启动不会重新启动一个 app, 只会把当前组件销毁并重启, 由于 $socket 是绑定到 VueVue.prototype 上的, 所以会出现这个问题

解决问题

  • 在源码中加入

    /**
    * 同一种消息只定义一次
    *
    * @param {string| symbol} event
    * @param {(...args: any[]) => void} listener
    * @memberof SocketConnection
    */
    one(event, listener) {
    	if (this.listeners(event).length === 0) {
    		this.on(event, listener)
    	}
    }
      
    Vue.mixin({
    	created() {
    		if (this.$options.sockets) {
    			const methods = Object.getOwnPropertyNames(this.$options.sockets)
    			methods.forEach(method => {
    				Socket.listen(method)
             // 使用 one 代替 on
    				Socket.one(method, data => this.$options.sockets[method].call(this, data))
    			})
    		}
      
    		if (this.$options.subscribe) {
    			Socket.one('authenticated', () => {
    				this.$options.subscribe.forEach(channel => {
    					Socket.invoke('join', channel)
    				})
    			})
    		}
    	}
    })
  • 其他监听也许要修改

  • 修改 app.vue

    created() {
      // 启动
      this.$socket.start()
    	// 监听 init 事件
      this.$socket.one('init', () => {
      	console.log('init')
      })
    	// 监听 reconnect 事件
      this.$socket.one('reconnect', () => {
      	console.log('reconnect')
      })
    	// 输出 $socket
      console.log(this.$socket)
    },

其他修改

关于 SocketConnection 实例 和 HubConnection 实例讨论

  • 个人观点: 在 app 中应该只有一个 SocketConnection 和 HubConnection 实例

  • 现有项目: 实现了 只有一个 SocketConnection 实例, 未实现只有一个 HubConnection 实例

  • 出现的问题, 在 断开 signal server 端时, 出现 init 和 reconnect 事件是无限循环

  • 修改:

    • 把 build HubConnection 实例放到 start 方法中, 并判断 socket 不为空时才创建

      async start(options = {}) {
        this.options = Object.assign(defaultOptions, options)
      
        // 组件重新加载时, 如果 socket 存在, 不需要新建
        if (!this.socket) {
          this.socket = new SignalR.HubConnectionBuilder()
            .configureLogging(SignalR.LogLevel.Information)
            .withUrl(this.connection, this.options)
            .build()
      
          this.socket.onclose(async () => {
            this.offline = true
            await this._initialize()
          })
          
        await this._initialize()
        }
      }
    • _initialize 方法中, 只做 HubConnection 的启动

      async _initialize() {
        try {
          await this.socket.start()
        } catch (error) {
          // 这里把重试改为了 5s, 减小客户端压力
          setTimeout(async () => {
            await this._initialize()
          }, 5000)
        }
      }
  • 其他修改

    • init 事件监听更名为 onstart
    • reconnect 事件监听更名为 onrestart
    • 新增事件监听 onclose

安装

$ npm install @wynnyo/vue-signalr --save

使用

import Vue from 'vue'
import VueSignalR from '@wynnyo/vue-signalr'

Vue.use(VueSignalR, 'SOCKET_URL');

new Vue({
  el: '#app',
  render: h => h(App),
  
  created() {
    this.$socket.start({
      log: false // Active only in development for debugging.
    });
    // socket 链接触发事件
		this.$socket.one('onstart', () => {
		})
    // socket 断开链接触发的事件
		this.$socket.one('onclose', () => {
		})
		// socket 重新链接触发事件
		this.$socket.one('onrestart', () => {
		})
  },
});

在其他组件中使用

Vue.extend({

  ...
  
  methods: {
  
    someMethod() {
      this.$socket.invoke('socketName', payloadData)
        .then(response => {
          ...
        })
    }
    
    async someAsyncMethod() {
      const response = await this.$socket.invoke('socketName', payloadData)
      ...
    }
    
  },

  // Register your listener here. 
  sockets: {
  
    // Equivalent of
    // signalrHubConnection.on('someEvent', (data) => this.someActionWithData(data))
    someEvent(data) {
      this.someActionWithData(data)
    }
    
    otherSomeEvent(data) {
      this.otheSomeActionWithOtherSomeData(data)
    }
    
  }

});