vue-socket.io 的使用及其局部引入解决方案

前言

基本的 HTTP 请求可以满足客户端访问数据的需要。如果需要“实时”刷新数据,可以采用轮询(设置一个定时器,每隔很短的一段时间发送 HTTP 请求重新获取数据)或长轮询(long poll,服务端收到 HTTP 请求后,将回调阻塞到有新数据产生)的方式。

轮询需要持续频繁地发送请求,会造成带宽和服务器资源的浪费。
长轮询需要服务器保持长连接,会增加服务器的开销。

相比于以上两种方式,WebSocket 真正实现了实时通讯。
轮询方式的背景是 HTTP 请求的被动性,也即客户端发起一次 Request,有且仅有一次 Response,服务端被动接收客户端的请求来进行操作。说白了,就是服务端没办法主动去跟客户端“说话”。

WebSocket 协议建立在 HTTP 协议的基础上,通过一次 HTTP 请求与服务器建立连接,以订阅-发布的模式让服务端可以主动联系客户端。

订阅-发布模式:客户端使用 主题(topic) 向服务端订阅消息,服务端在相关主题有新消息时,向所有订阅了该主题的客户端发布消息

vue-socket.io 在 vue 中的使用

使用前,强烈建议大家阅读官方文档与源码,也可以看一下知乎的使用介绍

安装依赖

npm install vue-socket.io --save

注:--save 安装的依赖将放在 package.json 中的 dependencies 下。与之对应的 --save-dev 将放在 devDependencies 这个情况下依赖不会打包到 dist 里。WebScoket 是项目运行时必须的依赖,所以只能使用 --save 进行安装。

在 main.js 全局引入模块

import Vue from 'vue'
import store from './store'
import App from './App.vue'
import VueSocketIO from 'vue-socket.io'

Vue.use(new VueSocketIO({
    debug: true,
    connection: 'http://metinseylan.com:1992',
    vuex: {
        store,
        actionPrefix: 'SOCKET_',
        mutationPrefix: 'SOCKET_'
    },
    options: { path: "/my-app/" } //Optional options
}))

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

在 main.js 引入模块将自动注册相关对象,可以在任意位置使用:

// 发送信息给服务端
this.$socket.emit('login',{
  username: 'username',
  password: 'password'
});

// 接收服务端的信息
this.sockets.subscribe('relogin', (data) => {
  console.log(data)
})

在模板 .vue 局部引入模块(特殊情况下使用)

在 script 标签内部,创建 socket 全局变量(VueSocketIO 的对象)。

import VueSocketIO from 'vue-socket.io';

var socket = new VueSocketIO({
    debug: true,
    connection: SocketIO(Setting.apiBaseURL),
    vuex(){}
});

在控制台打出 socket 对象,可以看到其内部封装了 io,Emitter,Listener 三个关键对象。稍微看一下,就会发现,io 对象和之前的 this.$socket 是同一个对象,因此可以使用:

// 发送信息给服务端
this.socket.io.emit('login',{
  username: 'username',
  password: 'password'
});

这个时候一个大大的问号就到了笔者的脑子里了,这个 this.sockets 是个什么玩意儿???
查了很多博客,这个 sockets 依旧葆有其神秘的面纱,没办法了,看源码去:

/**
     *  Assign runtime callbacks
     */
    beforeCreate(){

        if(!this.sockets) this.sockets = {};

        this.sockets.subscribe = (event, callback) => {
            this.$vueSocketIo.emitter.addListener(event, callback, this);
        };

        this.sockets.unsubscribe = (event) => {
            this.$vueSocketIo.emitter.removeListener(event, this);
        };

    },

Vue-Socket.io/src/mixin.js 文件里可以找到对 sockets 对象的定义。
很明显,之前的 this.sockets.subscribe 不过是对 Emitter 的小小封装,那么我们就可以使用:

// 接收服务端的信息
socket.emitter.addListener('relogin', (data) => {
  console.log(data)
})

结语

因为项目特殊需要,所以需要在模板中局部引入和使用 vue-socket.io,这个着实难倒了笔者。但也印证了看源码的重要性,查了大量的资料,试了各种奇奇怪怪的可能,不如看下源码,才知道自己被安排的明明白白的。


参考

  1. WebSocket 原理
  2. Vue.js 如何使用 Socket.IO
  3. Vue-Socket.io 源码

个人总结,敬请指正。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值