Vue Socket.io源码解读

2020-06-16 05:46:53易采站长站整理

Observer.js


constructor(connection, store) {
// 这里很明白吧,就是判断这个connection是什么类型
// 这里的处理就是你可以传入一个连接好的socket实例,也可以是一个url
if(typeof connection == 'string'){
this.Socket = Socket(connection);
}else{
this.Socket = connection
}

// 如果有传进vuex的store可以响应在store中写的mutations和actions
// 这里只是挂载在这个oberver实例上
if(store) this.store = store;

// 监听,启动!
this.onEvent()

}

这个Observer.js里也主要是写了一个Observer的class,以上是它的构造函数,构造函数第一件事是判断connection是不是字符串,如果是就构建一个socket实例,如果不是,就大概是个socket的实例了,然后直接挂载在它的对象实例上。其实这里我觉得可以参数检查严格点, 比如字符串被人搞怪地可能会传入一个非法的url,对吧。这个时候判断下,抛出一个error提醒下也好,不过应该也没人这么无聊吧,2333。然后如果传入了store,也挂在对象实例上吧。最后就启动监听事件啦。我们看看onEvent的逻辑


onEvent(){
// 监听服务端发来的事件,packet.data是一个数组
// 第一项是事件,第二个是服务端传来的数据
// 然后用emit通知订阅了该信号的回调函数执行
// 如果有传入了vuex的store,将该事件和数据传入passToStore,执行passToStore的逻辑
var super_onevent = this.Socket.onevent;
this.Socket.onevent = (packet) => {
super_onevent.call(this.Socket, packet);

Emitter.emit(packet.data[0], packet.data[1]);

if(this.store) this.passToStore('SOCKET_'+packet.data[0], [ ...packet.data.slice(1)])
};

// 这里跟上面意思应该是一样的,我很好奇为什么要分开写,难道上面的写法不会监听到下面的信号?
// 然后这里用一个变量暂存this
// 但是下面都是箭头函数了,我觉得没必要,毕竟箭头函数会自动绑定父级上下文的this
let _this = this;

["connect", "error", "disconnect", "reconnect", "reconnect_attempt", "reconnecting", "reconnect_error", "reconnect_failed", "connect_error", "connect_timeout", "connecting", "ping", "pong"] .forEach((value) => {
_this.Socket.on(value, (data) => {
Emitter.emit(value, data);
if(_this.store) _this.passToStore('SOCKET_'+value, data)
})
})
}

这里就是有点类似重载onevent这个函数了,监听到事件后,将数据拆包,然后通知执行回调和传递给store。大体的逻辑是这样子。然后这代码实现有两部分,第一部分和第二部分逻辑基本一样。只是分开写。(其实我也不是很懂啦,如果很有必要的话,我猜第一部分的写法还监听不了第二部分的事件吧,所以要另外监听)。最后只剩下一个passToStore了,其实也很容易懂