您的位置:首页 > Web前端 > JavaScript

<srcipt src="/socket.io/socket.io.js"></script>加载的资源是从哪儿冒出来的?

2018-02-12 13:49 591 查看
这个标题可能起的不太高级,或者表述不清楚。这里解释一下,其实就是弄清楚
<srcipt type="text/javascript" src="/socket.io/socket.io.js"></script>
这句代码加载的资源是哪里来的。如果觉得过程太繁琐,就直接看总结把。

首先我们来看一下使用socket.io前端代码的实现:

<!DOCTYPE html>
<html>
<head>
<title>socket.io</title>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div></div>
<script type="text/javascript">
var socket = io("ws://10.10.10.96:8080"); //通过ip和端口建立一个socket client
socket.on('connect', function(){
console.log('connect a socket client');
});
</script>
</body>
</html>


使用非常简单,就是去服务器加载socket.io.js这个js,然后浏览器解析这个文件,获取io这个实例对象,这个实例里面封装了关于wbsocket的相关方法,没什么难理解的。但是我要说的是socket.io.js这个外部脚本是如何获取到的。写nodejs的朋友都知道外部脚本,样式,图片等这些文件是属于静态资源,在服务端我们通常会有一个静态资源文件夹public在express中我们通过:

app.use(express.static(__dirname+'/public'))


来实现资源静态化,其实实现原理很简单,请求过来的时候根据请求url判断是不是请求静态资源,如果是就将public中对应url的文件读出来然后返回就行。但是我们会发现

<script type="text/javascript" src="/socket.io/socket.io.js"></script>


请求的资源是不在我们的静态资源文件夹里面的。那这个文件是哪里来的呢?这个时候我们第一反应应该想到我们引入的socket.io包了。打开这个模块我们可以看见



这里我们可以看见一个socket.js,但是他不是我们前面提到那个socket.io.js,至于问什么不是,你打开看一下,里面的编写规范完全是按照commonJS那一套来的,而commonJS在不编译的情况下,浏览器只能说“臣妾无能为力啊”。那他在是从哪儿来的呢?大家可能会注意到socket.iomo模块下还有几个命名为socket***的模块,不要怀疑自己的第一感觉,他们肯定是‘亲戚’关系,他就在socket.io-clientmo模块里面



这里我们就不买关子了,居然找到资源文件了,哪我们就看作者是如何将这个资源文件静态化的。这里我们还是要回到前面的socket.io模块中去,因为他是我们直接引入的模块,打开入口文件index.js,从代码中收索我们要找的socket.io相关字样很快我们可以发现这一段代码:

var clientSource = undefined;//定义静态资源内容变量

/**
* Server 构造函数.
*
* @param {http.Server|Number|Object} srv http server, port or options
* @param {Object} [opts]
* @api public
*/
function Server(srv, opts){
if (!(this instanceof Server)) return new Server(srv, opts);
if ('object' == typeof srv && srv instanceof Object && !srv.listen) {
opts = srv;
srv = null;
}
opts = opts || {};
this.nsps = {};
this.path(opts.path || '/socket.io');
this.serveClient(false !== opts.serveClient);
this.parser = opts.parser || parser;
this.encoder = new this.parser.Encoder();
this.adapter(opts.adapter || Adapter);
this.origins(opts.origins || '*:*');
this.sockets = this.of('/');
//这一句实现了静态资源socket.io.js
if (srv) this.attach(srv, opts);
}


我们看看我们在服务端express是如何搭建socket服务的:

var app = require("express")();
var socket = require("socket.io");
var port = 8080
app.set('port', port);
var server = http.createServer(app);
var io = socket(server);
server.listen(port);


顺便说一句express4.x和koa2在使用socket.io上都大同小异。socket(server)其实在启动websocket服务的时候,同时还相当于给这个http服务增加了一条处理/socket.io/socket.io.js的路由,(这里说明一点,不一定是websocket服务,socket.io做了降价处理,当浏览器不支持websocket时,他会自动切换到comet4j模式上去,这里我们不考虑comet4j),我们也可以不将websocket服务挂载到当前端口,也可以另外起端口,这里不多说,主要还是弄清楚socket.io.js时哪里来的。

总结:

前面将来这么多,其实‘src=”/socket.io/socket.io.js”‘在nodejs 服务的实现方式有两种:

var io = socket(server);


一种就是当传入server是一个http对象的时候,上面这句代码会在出传入的server对象上添加两条处理/socket.io/socket.io.js和/socket.io/socket.io.js.map的路由,然后将对应的文件响应给http请求,

另外一种就是当传入的server是一个数字(端口)的时候,socket(server)会重新启动一个监听在该端口的http服务,然后将上面提到的哪两条路由挂在新端口的http服务下。这样当我们在使用

<script type="text/javascript" src="/socket.io/socket.io.js"></script>


加载外部脚本的时候就能保证socket.io.js的资源的正确加载了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nodejs socket-io websocket
相关文章推荐