Javascript 如何从express应用程序获取http.server?

Javascript 如何从express应用程序获取http.server?,javascript,node.js,express,socket.io,Javascript,Node.js,Express,Socket.io,我正在编写一个服务器端node.js应用程序,它使用express处理HTTP请求,并添加WebSocket(socket.io)支持。但是,我无法访问启动HTTP服务器的代码。我正在编写一个快速路由器和函数来处理各种URL。我的代码如下所示: var express = require('express'); var router = express.Router(); router.post( myURL, myFunction ); 设置路由器时,我想使用socket.io来监听webs

我正在编写一个服务器端node.js应用程序,它使用express处理HTTP请求,并添加WebSocket(socket.io)支持。但是,我无法访问启动HTTP服务器的代码。我正在编写一个快速路由器和函数来处理各种URL。我的代码如下所示:

var express = require('express');
var router = express.Router();
router.post( myURL, myFunction );

设置路由器时,我想使用socket.io来监听websocket连接。我无法将
express
express()
传递到
require('socket.io')(xxx)
,我需要传递http.Server对象。但是既然我没有启动服务器,我怎么才能得到它呢?

您也可以使用下面的代码来完成同样的事情

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(80);

有关更多信息,我建议您参考

,据我所知,Express
app
对象不知道服务器对象。按照Express中的工作方式,
app
对象被赋予服务器对象,而不是反过来。事实上,一个
app
对象甚至可以用于多个服务器(有时用于http和https服务器)

您可以通过
req.connection.server
从请求处理程序中访问服务器对象,但这是作为请求上下文的一部分来自服务器的,而
应用程序
对象本身并不知道这一点

因此,如果希望在初始化时访问服务器对象以与socket.io一起使用,则必须将服务器对象捕获到创建它的变量中

问题中显示的代码不会创建或启动服务器。使用Express启动服务器的常用两种方法如下:

var express = require('express');
var app = express();
// Express creates a server for you and starts it
var server = app.listen(80);
或者,您自己创建服务器并将express作为处理程序传递给它:

var express = require('express');
var app = express();
// you explicitly create the http server
var server = require('http').createServer(app);
server.listen(80);
在上述每种情况下,最终都会在变量中包含服务器对象,然后可以将其与socket.io一起使用


在处理来自传递给请求处理程序的
req
res
对象的请求时,可以从Express route处理程序内部访问服务器

res.connection.server
req.connection.server

您可以编写一个简单的包装器来实例化或获取Express应用程序中的Socket IO实例,方法是将以下内容放入某个文件中:

//Dependencies
const socketIo = require('socket.io');

//Placeholder for instance
let io;

//Export handler to instantiate or get instance
module.exports = function(server) {
  if (server) {
    io = socketIo(server);
  }
  return io;
};
然后,您可以在设置Express时以通常的方式实例化此实例:

const app = require('express')();
const server = require('http').Server(app);
const io = require('./path-to-your-file')(server);
当您以后在路线或其他地方的代码中需要它时,您可以按如下方式获得它:

const io = require('./path-to-your-file')();

这当然是一个简化的示例,但您可以修改逻辑以满足您的需要。

当您调用
app.listen()
时,服务器将返回。例如:

const server = app.listen(process.env.NODE_PORT, () => {
  console.log('Listening', server.address());
});

看看express
listen
功能是如何实现的:

app.listen = function listen() {
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};
因此,如果显式存储http服务器实例,基本上并不重要:

var server = require('http').createServer(app);
或者参考express的返回值
listen

var server = app.listen()

从技术上讲,你指的是同一件事,这让我很困惑。。。也许最好明确地期望开发人员将express app作为http服务器构造函数参数传递,因为
app.listen()
基本上是围绕
http.server(参数)

的包装器,我在使用带套接字io的wepack devServer时遇到了这个问题,jfriend00的注释帮助了我。我使用这个技巧:

let server;
app.use((req, res, next) => {
    if (!server){
        server = req.connection.server;
        //do fancy staffs with http-server
    }
    next();
})

尝试从myFunction中的req访问服务器,启动服务器的代码在哪里?您显示的代码根本不会启动服务器。您的代码中应该有一个
xxx.listen()
。据我所知,您无法从Express
app
对象获取服务器对象。它不知道服务器。但是你的代码不需要xxx.listen()就会知道服务器,所以你需要从那里获取它。是的,这就是我的观点。启动服务器的代码在其他地方,我的代码所做的就是添加一个路由器。我无法访问调用
listen()
或调用
createServer
的代码,因此我希望有办法从express或其他地方获取它。在第一个注释中链接的答案有帮助。@ GrimeEpReave:嗯,在处理请求的过程中,您可以从REQ或RES对象中获得服务器,但这不是您所要求的。我怎样才能做HTTPS?我的语法与您使用的相同,但var server=require('https')。server(app);这似乎不起作用。