Socket.io-client源码分析
Socket.io-client source code analysis
根据node_modlues
中socket.io-client
的文件结构,大概画了张UML图。
从图片中可以清楚地看到模块中lib
文件夹下各文件的依赖关系。
Note:带箭头的虚线表示依赖关系,如socket.js需要依赖on.js ,则箭头指向on.js,即依赖对象指向被依赖的对象。
下面就对lib目录下文件进行分析
on.js
/**
* Helper for subscriptions.
*
* @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
* @param {String} event name
* @param {Function} callback
* @api public
*/
function on (obj, ev, fn) {
obj.on(ev, fn);
return {
destroy: function () {
obj.removeListener(ev, fn);
}
};
}
/**
* Emitter是一个模块,实现了mixin模式,obj = Emitter(obj) 或者 obj = new Emitter;
* obj.on(ev, fn) 是给事件ev注册了一个函数
* 函数返回一个带有去除监听事件功能的对象。
url.js
/**
* URL parser.
*
* @param {String} url
* @param {Object} An object meant to mimic window.location.
* Defaults to window.location.
* @api public
*/
function url (uri, loc) {
var obj = uri;
// loc 是一个模仿window.location的对象
// 默认是window.location
loc = loc || (typeof location !== 'undefined' && location);
//如果uri不存在的话,默认值为当前浏览器地址的协议加上主机名。
//e.g 浏览器地址栏为https://socket.io/docs/client-api/#socket-disconnected
// 则uri = https://socket.io
if (null == uri) uri = loc.protocol + '//' + loc.host;
// relative path support
// 路径支持
// '//socket.io' => https://socket.io
// '/docs' => socket.io/docs
if ('string' === typeof uri) {
if ('/' === uri.charAt(0)) {
if ('/' === uri.charAt(1)) {
uri = loc.protocol + uri;
} else {
uri = loc.host + uri;
}
}
//不使用超文本安全传输协议或者websocket security
if (!/^(https?|wss?):\/\//.test(uri)) {
debug('protocol-less url %s', uri);
if ('undefined' !== typeof loc) {
//loc为空的情况下,使用当前浏览器地址使用协议
uri = loc.protocol + '//' + uri;
} else {
//否则使用超文本安全传输协议
uri = 'https://' + uri;
}
}
// parse
debug('parse %s', uri);
// 使用engine.io-client解析uri
obj = parseuri(uri