已使用Express为何仍需引入http模块?Socket.io启动疑问
关于Socket.IO与Express服务器的疑问解答
嘿,这个问题问得特别到位!我来一步步帮你理清逻辑~
为什么需要var http = require('http').Server(app);?
首先得明确一个关键点:Express的app并不是一个完整的HTTP服务器对象,它本质上是一个处理HTTP请求的回调函数。而Socket.IO需要绑定到一个标准的Node.js HTTP服务器实例上,才能建立WebSocket连接,同时让HTTP请求(比如Express处理的网页、API)和WebSocket连接共享同一个端口。
require('http').Server(app)这句话的作用,就是把Express的app作为请求处理器,挂载到原生Node.js HTTP服务器上,这样就得到了Socket.IO需要的服务器实例。
能不能用app.listen替代http.listen,并把app传入io?
当然可以!而且这种写法更简洁~
其实app.listen()方法的内部逻辑,就是帮你自动创建了一个HTTP服务器实例,然后调用它的listen方法,最后返回这个服务器对象。所以你完全可以直接把app.listen()返回的结果传给Socket.IO,不需要手动创建http.Server。
举个实际的例子:
官方常见写法(手动创建HTTP服务器)
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); http.listen(3000, function(){ console.log('listening on *:3000'); });
简化写法(用app.listen获取服务器实例)
var app = require('express')(); // app.listen返回的就是创建好的HTTP服务器实例 var server = app.listen(3000, function(){ console.log('listening on *:3000'); }); // 把server传给Socket.IO就行 var io = require('socket.io')(server);
这两种写法的效果完全等价,因为Express源码里app.listen的实现大概是这样的:
app.listen = function() { var server = http.createServer(this); // this就是Express的app对象 return server.listen.apply(server, arguments); };
需要注意的是:不能直接把Express的app对象传给Socket.IO,必须传HTTP服务器实例,因为Socket.IO依赖原生HTTP服务器的底层接口来处理WebSocket握手。
内容的提问来源于stack exchange,提问作者guy1733
相关产品推荐
相关产品推荐

